繁体   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