不使用Autofac名称空间

时间:2017-06-11 19:06:06

标签: c# autofac

我试图弄清楚每次从容器中解析实例时如何获得新的生命周期范围。我想这样做,而不需要知道有关Autofac的依赖组件。

我正在创建一个具有"主服务器" (IMasterServer)组件和零个或多个"会话服务器" (ISessionServer)组件。主服务器和会话服务器都有自己的IMessageBroker依赖项。只要主服务器从消息代理获得消息,主服务器就会创建一个新的会话服务器。

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

所以,问题是,如何将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?

但是,除非我遗漏了某些内容,否则这意味着注入依赖项的组件(在我的情况下为IMasterServer)需要了解Autofac,因为它的ctor签名必须包含{ {1}}输入。

到目前为止我所拥有的:

Owned<T>

您可以看到MasterServer具体类需要使用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关系类型定义会话工厂。

每次通过注入Owned<T>的工厂解决ISessionServer时,如何使用Autofac创建新的生命周期范围,而组件不需要知道有关正在使用的特定DI容器的任何信息?

1 个答案:

答案 0 :(得分:0)

我一直认为让特定于Autofac的代码进入工厂类是两个罪恶。 所以,如果我在你身边,我会使用Owned<T>课程,称之为一天,继续前进。它是一个出色的解决方案,并且可以像Autofac一样自动处理每个组件的自动化。

请记得在需要时致电Dispose或您拥有的SessionServer,否则您将泄露资源。

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

包含Owned<T>的单一参考似乎是一个非常可接受的权衡。

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

例如:您公开了一个工厂类,然后SessionServer独立出来。 以这种方式管理范围变得很难。

更简洁的方法是将Disposable用于using语句:

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