gpt4 book ai didi

c# - 不使用 Autofac 命名空间的隐式解析范围

转载 作者:太空宇宙 更新时间:2023-11-03 15:04:20 24 4
gpt4 key购买 nike

每次我从容器中解析一个实例时,我都在尝试弄清楚如何获得一个新的生命周期范围。我想在依赖组件不需要了解 Autofac 的情况下执行此操作。

我正在创建一个 .NET Core 服务器应用程序(控制台应用程序),它有一个“主服务器”(IMasterServer)组件和零个或多个“ session 服务器”(ISessionServer)组件。主服务器和 session 服务器都有自己的 IMessageBroker依赖。每当从消息代理收到消息时,主服务器将创建一个新的 session 服务器。

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

所以,问题是,我怎样才能注入(inject) ISessionServer厂进IMasterServer这样每次调用该工厂时,都会为结果 ISessionServer 创建一个新的生命周期范围。实例?以及如何做到这一点,使得所有组件都不需要了解 Autofac?

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

Can I create an implicit Lifetime scope within a factory?

Is it possible to create a new scope whenever a component is resolved?

但是,除非我遗漏了什么,否则这意味着将注入(inject)依赖项的组件(在我的例子中是 IMasterServer)需要了解 Autofac,因为它的 ctor 签名必须包含 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> 定义 session 工厂关系类型。

如何使用 Autofac 每次都创建一个新的生命周期范围 ISessionServer通过工厂注入(inject)MasterServer解决, 而组件不需要知道任何关于正在使用的特定 DI 容器的信息?

最佳答案

我一直觉得让 Autofac 特定代码滑入工厂类是两害相权取其轻。所以,如果我在你身边,我只会使用 Owned<T>上课,收工,继续前进。这是一个出色的解决方案,并且与 Autofac 一如既往地自动处理每个组件。

记得调用Dispose或您拥有的 SessionServer在需要的时候,否则你会泄漏资源。

AFAICT Autofac 方法不允许您编写 100% DI 自由代码。因此,您需要以某种方式在某处引用它。

要包含的单个引用 Owned<T>似乎是一个相当可以接受的权衡。

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

例如:你公开了一个工厂类,然后 SessionServer 就自己出来了。以这种方式管理范围变得困难。

更简洁的方法是在 using 语句中使用 Disposable:

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

关于c# - 不使用 Autofac 命名空间的隐式解析范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44487671/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com