我在我的UWP应用程序中使用autofac
。
我在后端使用facade模式,它由IFacade
接口表示。
public interface IFacade
{
/* forwards view-models' calls to different parts of the backend */
}
我的UWP应用程序的视图模型使用IFacade
的实现,其具体实现通过UWP autofac
实例中的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
实现最终会引用那些可怕的构造函数来引用很多服务的接口,这会让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
构造函数最后一个看起来更容易接受的解决方案(好吧......我可以接受)就是使用DI注入一个非静态的ServiceLocator。这是一种解决方案2)。但是,我知道ServiceLocator是frowned upon。
答案 0 :(得分:1)
因此,另一种方法是创建一些较小的Facade Services,然后将这些服务注入主外观。
例如,您可以为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/