C# 不使用Autofac命名空间解析时的隐式作用域

C# 不使用Autofac命名空间解析时的隐式作用域,c#,autofac,C#,Autofac,每次从容器中解析实例时,我都试图弄清楚如何获得新的生存期范围。我想在不需要了解Autofac的情况下完成此操作 我正在创建一个.NET核心服务器应用程序(控制台应用程序),它有一个“主服务器”(IMasterServer)组件和零个或多个“会话服务器”(ISessionServer)组件。主服务器和会话服务器都有自己的IMessageBroker依赖关系。每当主服务器从MessageBroker获得消息时,它将创建一个新的会话服务器 问题是每个会话服务器实例都需要自己的IMessageBroke

每次从容器中解析实例时,我都试图弄清楚如何获得新的生存期范围。我想在不需要了解Autofac的情况下完成此操作

我正在创建一个.NET核心服务器应用程序(控制台应用程序),它有一个“主服务器”(
IMasterServer
)组件和零个或多个“会话服务器”(
ISessionServer
)组件。主服务器和会话服务器都有自己的
IMessageBroker
依赖关系。每当主服务器从MessageBroker获得消息时,它将创建一个新的会话服务器

问题是每个会话服务器实例都需要自己的
IMessageBroker
,我认为我不能使用
InstancePerDependency()
因为
ISessionServer
的其他子组件也需要访问
IMessageBroker
,所以消息代理需要是会话范围内的单个实例。因此,我的想法是,当主服务器生成一个新会话时,它应该在一个新的生命周期内生成,并且我可以使用
InstancePerLifetimeScope()
注册
IMessageBroker
依赖项

因此,问题是,如何将
ISessionServer
工厂注入
IMasterServer
中,以便每次调用该工厂时,都为生成的
ISessionServer
实例创建一个新的生存期范围?如何做到这一点,使所有组件都不需要了解Autofac

这两个SO问题都建议使用
Owned
关系:

但是,除非我遗漏了什么,否则这意味着将注入依赖项的组件(
IMasterServer
在我的例子中)需要了解Autofac,因为它的ctor签名必须包括
Owned
类型

到目前为止,我所拥有的:

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);
    }
}
使用Autofac.Features.OwnedInstances;
类MasterServer:IMasterServer
{
私人IMessageBroker-mMessageBroker;
私有Func mSessionServerFactory;
公共主人(
Func messageBrokerFactory,
Func会话服务器工厂
)
{
mMessageBroker=messageBrokerFactory(“主”);
mSessionServerFactory=sessionServerFactory;
}
}
类会话服务器:ISessionServer
{
私人IMessageBroker-mMessageBroker;
私有字符串mId;
公共会话服务器(
Func messageBrokerFactory
)
{
mId=Guid.NewGuid().ToString();
mMessageBroker=messageBrokerFactory(mId);
}
}
您可以看到MasterServer具体类需要使用
Autofac.Features.OwnedInstances
命名空间,以便使用
Owned
关系类型定义会话工厂


如何使用Autofac在每次通过工厂注入主服务器解决ISessionServer问题时创建新的生存期作用域,如果组件不需要了解所使用的特定DI容器,我总是觉得让特定于Autofac的代码滑到factory类上是两件坏事中的一件。 所以,如果我在你身边,我会使用
拥有的
类,今天到此为止,继续前进。这是一个很好的解决方案,使所有组件的处理都像Autofac一样自动化

只要记住在需要时调用
Dispose
或您自己的
SessionServer
,否则您将泄漏资源

AFAICT的Autofac方法不允许您编写100%无DI的代码。所以你需要在某个地方引用它

一个包含
Owned
的引用似乎是一个可以接受的折衷方案

让我指出您的设计(或您所包含的部分)中的一个问题:没有简单的方法将ISessionServer链接到一次性作用域

例如:您公开了一个工厂类,然后会话服务器就独立运行了。 以这种方式管理作用域变得很困难

一种更干净的方法是在使用语句中使用一次性塑料:

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

谢谢你的意见。随着我继续开发这个应用程序,我发现在其他地方,实现有价值的Autofac功能将导致我的更多组件需要了解Autofac。我想我应该接受你的建议。关于你建议将
SessionServer
包装在using块中,我认为我做不到,因为
MasterServer
需要挂起一组
SessionServer
实例。当它被处理掉的时候,它会处理掉的。我建议你在特定的地方使用Autofac。例如,您可以使一个类
SessionServerHandle
实现一个
getSessionServer()
方法,并负责创建一个特定的Autofac作用域,实例化和处理
SessionServer
实例。简而言之,一个负责管理工作单元的类。我的经验法则是,实现类应该是无Autofac的。像工厂之类的特殊类是我让DI代码溜进实现的地方。