[英]How to use Dependency Injection with the Facade pattern?
我在UWP应用程序中使用了autofac
。
我正在为我的后端使用外观模式,它由IFacade
接口表示。
public interface IFacade
{
/* forwards view-models' calls to different parts of the backend */
}
我的UWP应用程序的视图模型使用IFacade
的实现,其具体实现通过UWP的App
实例中的autofac
进行解析。
public class App : Application
{
...
private IFacade InitializeDependencies()
{
var containerBuilder = new ContainerBuilder();
// Registers all the platform-specific implementations of services.
containerBuilder.RegisterType<LoggingService>().As<ILoggingService>().SingleInstance();
containerBuilder.RegisterType<SQLitePlatformService>().As<ISQLitePlatformService>().SingleInstance();
containerBuilder.RegisterType<DiskStorageService>().As<IDiskStorageService>().SingleInstance();
containerBuilder.RegisterType<IdentityProviderFactoryService>().As<IIdentityProviderFactoryService>().SingleInstance();
containerBuilder.RegisterType<DefaultVaultService>().As<IVaultService>().SingleInstance();
containerBuilder.RegisterType<LocationService>().As<ILocationService>().SingleInstance();
containerBuilder.RegisterType<NavigationService>().As<INavigationService>().SingleInstance();
// Registers all the dependencies of the Backend project.
var backendDependencies = new Dependencies();
backendDependencies.Setup(containerBuilder);
// Resolves the IFacade.
var container = containerBuilder.Build();
var lifetimeScope = container.BeginLifetimeScope();
return backendDependencies.ResolveFacade(lifetimeScope);
}
我的后端有很多服务,而IFacade
实现最终以引用许多服务接口的可怕构造函数结尾,这会使Bob叔叔畏缩。
internal sealed Facade : IFacade
{
public Facade(ISessionService sessionService, IEntitiesRepository entitiesRepository, ISynchronizationService synchronizationService, IVaultService vaultService, IIdentityProviderFactoryService identityProviderFactoryService, IDemoTapeService demoTapeService, IDiskStorageService diskStorageService)
{
/* Saves the references as read-only fields. */
}
}
题
与ServiceLocator相反,使用DI迫使我们使所有需要的依赖项可见。 我不确定我是否正确使用了依赖注入。
我该怎么办,以使我的Facade
类的构造函数没有那么多参数?
解决方案尝试
我可以更改Facade
类,并通过公共财产注入服务。 我不喜欢很多public get / set
因为我的IFacade
合同现在表明在创建Facade
实现后可以更改那些属性,这不是我要支持(和调试)的东西。
另一个选择是将接口聚合在一起(我称之为SomethingContext
类),但是很难理解这些接口组的含义。
Facade
构造函数中不是静态的ServiceLocator 似乎更可接受(对我来说可以接受)的最后一个解决方案是使用DI注入非静态ServiceLocator。 这是一种解决方案2)。 但是,我知道的服务定位是什么,是令人难以接受的 。
因此,另一种方法是创建一些较小的外观服务,然后将这些服务注入主外观。
例如,您可以创建这样的小门面INavigationService
和ILocationService
:
public class GeographyService : IGeographyService
{
public GeographyService(
INavigationService navigationService,
ILocationService locationService)
{
}
}
ISQLitePlatformService
和DiskStorageService
也是如此:
public class StorageService : IStorageService
{
public StorageService(
ISQLitePlatformService databaseService,
DiskStorageService diskStorageService)
{
}
}
当然,这只是一个想法的例子。
通常认为这种方法比聚合所有依赖项( http://autofaccn.readthedocs.io/en/latest/advanced/aggregate-services.html )或ServiceLocator(反)模式的聚合服务更好。 您还可以在此处阅读有关此内容的一些想法: http : //blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.