我正在使用 autofac
在我的 UWP 应用程序中。
我正在使用 facade我的后端的模式,它由 IFacade
表示界面。
public interface IFacade
{
/* forwards view-models' calls to different parts of the backend */
}
我的 UWP 应用程序的 View 模型正在使用
IFacade
的实现其具体实现通过autofac
解决在 UWP 的 App
实例。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
的实现最终导致那个可怕的构造函数引用了很多服务的接口(interface),这会让鲍勃叔叔畏缩不前。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 迫使我们使所有需要的依赖项可见。我不确定我是否正确使用了依赖注入(inject)。
我该怎么做才能让我的
Facade
的构造函数类没有那么多参数?尝试过的解决方案
我可以更改
Facade
类并通过公共(public)属性注入(inject)服务。我不喜欢很多public get / set
作为我的IFacade
契约(Contract)现在将表明这些属性可以在 Facade
之后更改。创建了实现,这不是我想要支持(和调试)的东西。另一种选择是将接口(interface)聚合在一起(我称之为
SomethingContext
类),但是很难理解这些接口(interface)组的含义。Facade
中注入(inject)一个非静态的 ServiceLocator构造函数 最后一个似乎更可接受的解决方案(嗯......我可以接受)是使用 DI 注入(inject)非静态 ServiceLocator。这是一种解决方案2)。但是,我知道 ServiceLocator 是 frowned upon .
最佳答案
所以另一种方法是创建一些较小的外观服务,然后将这些服务注入(inject)主外观。
例如,您可以为 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/
关于c# - 如何将依赖注入(inject)与 Facade 模式一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49845011/