c# - 如何将依赖注入(inject)与 Facade 模式一起使用?

标签 c# .net uwp autofac

我正在使用 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)

  • 另一种选择是将接口(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/

    相关文章:

    c# - WebApi + 简单注入(inject)器 + OWIN

    c# - 将 mongodb 连接到 C#

    c# - log4net - 自定义属性日志记录

    .net - ASP.NET MVC 和测试驱动开发

    c# - 渲染半透明/透明叠加

    c# - CalendarDatePicker 绑定(bind)空值

    C#: 'IEnumerable<Student>' 不包含 'Intersect' 的定义

    .net - 可以访问 VB.NET 类库中的 My.Forms 对象吗?

    c# - 检查打包的 WPF 应用程序是随启动运行还是手动运行?

    c# - UWP 应用程序尝试将本地 html 文件加载到 webview 控件