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