簡體   English   中英

如何在Facade模式中使用依賴注入?

[英]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類的構造函數沒有那么多參數?

解決方案嘗試

  1. 屬性

我可以更改Facade類,並通過公共財產注入服務。 我不喜歡很多public get / set因為我的IFacade合同現在表明在創建Facade實現后可以更改那些屬性,這不是我要支持(和調試)的東西。

  1. 聚合接口

另一個選擇是將接口聚合在一起(我稱之為SomethingContext類),但是很難理解這些接口組的含義。

  1. 注入在Facade構造函數中不是靜態的ServiceLocator

似乎更可接受(對我來說可以接受)的最后一個解決方案是使用DI注入非靜態ServiceLocator。 這是一種解決方案2)。 但是,我知道的服務定位是什么,是令人難以接受的

因此,另一種方法是創建一些較小的外觀服務,然后將這些服務注入主外觀。

例如,您可以創建這樣的小門面INavigationServiceILocationService

public class GeographyService : IGeographyService
{
    public GeographyService(
        INavigationService navigationService, 
        ILocationService locationService)
    { 
    }
}

ISQLitePlatformServiceDiskStorageService也是如此:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM