簡體   English   中英

不使用Autofac命名空間的隱式作用域

[英]Implicit scope on resolve without using Autofac namespace

我試圖弄清楚每次我從容器解析實例時如何獲得新的生存期范圍。 我想要執行此操作而無需依賴組件來了解Autofac。

我正在創建一個.NET Core服務器應用程序(控制台應用程序),它具有一個“主服務器”( IMasterServer )組件和零個或多個“會話服務器”( ISessionServer )組件。 主服務器和會話服務器都具有自己的IMessageBroker依賴性。 每當主服務器從消息代理獲取消息時,它將創建一個新的會話服務器。

問題是每個會話服務器實例都需要自己的IMessageBroker ,並且我認為我不能使用InstancePerDependency()因為ISessionServer其他子組件也需要訪問IMessageBroker因此消息代理必須是會話范圍。 所以我的想法是,當主服務器產生新會話時,它應該在新的生命周期范圍內進行,並且我可以使用InstancePerLifetimeScope()注冊IMessageBroker依賴項。

因此,問題是,如何將ISessionServer工廠注入IMasterServer ,以便每次調用該工廠時,都為生成的ISessionServer實例創建一個新的生存期作用域? 怎樣才能使所有組件都不需要了解Autofac?

這兩個SO問題都建議使用Owned<T>關系:

我可以在工廠內創建隱式生命周期范圍嗎?

解析組件后是否可以創建新的作用域?

然而,除非我失去了一些東西,這意味着到其中的依存度將(要注射的成分IMasterServer在我的情況)需要了解Autofac,因為它的構造函數的簽名必須包括Owned<T>類型。

到目前為止,我有:

using Autofac.Features.OwnedInstances;

class MasterServer : IMasterServer
{
    private IMessageBroker mMessageBroker;
    private Func<Owned<ISessionServer>> mSessionServerFactory;

    public Master(
        Func<string, IServerMessageBroker> messageBrokerFactory,
        Func<Owned<ISessionServer>> sessionServerFactory
    )
    {
        mMessageBroker = messageBrokerFactory("master");
        mSessionServerFactory = sessionServerFactory;
    }
}


class SessionServer : ISessionServer
{
    private IMessageBroker mMessageBroker;
    private string mId;

    public SessionServer(
        Func<string, IMessageBroker> messageBrokerFactory
    )
    {
        mId = Guid.NewGuid().ToString();
        mMessageBroker = messageBrokerFactory(mId);
    }
}

您可以看到MasterServer具體類需要使用Autofac.Features.OwnedInstances命名空間,以便使用Owned<T>關系類型定義會話工廠。

每次通過ISessionServer通過注入到MasterServer的工廠來解析ISessionServer我如何使用Autofac創建新的生存期作用域,而組件無需了解所使用的特定DI容器的任何信息?

我一直覺得讓特定於Autofac的代碼放到工廠類上可以減少兩個弊端。 因此,如果我在您里面,我將只使用Owned<T>類,將其命名為“ day”然后繼續。 這是一個極好的解決方案,並且使Autofac像往常一樣自動處理所有組件。

只需記住在需要時調用Dispose或您自己的SessionServer ,否則您將泄漏資源。

AFAICT的Autofac方法不允許您編寫100%無DI的代碼。 因此,您需要在某些地方引用它。

包含Owned<T>單個引用似乎是可以接受的折衷方案。

讓我指出您的設計(或包含的零件)中的一個問題:沒有簡單的方法將ISessionServer鏈接到一次性作用域中。

例如:您公開了一個工廠類,然后SessionServer自行退出。 以這種方式管理范圍變得困難。

一種更干凈的方法是在Disable語句中使用Disposable:

using (var sessionServer = sessionFactory.GetServer())
{
    // do something with sessionServer.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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