0

是否有任何具有线程安全类型注册的 .net IOC 容器?

我有许多在应用程序的生命周期内固定的绑定 - 但是有一些注册需要在“每个线程”或“每个请求”的基础上进行调整。当这个应用程序的线程被回收到线程池或从线程池回收时,少数动态 IOC 注册将被清除或覆盖,因为新请求被分派。

澄清一下,下面是基于 Unity 的示例代码,它将 WCF 服务与容器“模块”或“注册表”的概念相结合。

public class AccountServiceRegistry : UnityContainerExtension, IBindingOverride
{
    //From UnityContainerExtension
    protected override void Initialize() 
    {
        Container.RegisterType<IAccountService, AccountService>();
    }

    //From IBindingOverride
    public void ReInitialize(IUnityContainer child, string action, object[] parms){

        child.RegisterType<AccountService>(new InjectionProperty("log"), new InjectionProperty("dao"));

        child.AddNewExtension<DataAccessRegistry>();

        string connectionString = action == "GetMoreData" ? "Alpha" : "Bravo";

        child.Configure<IDataAccessConfig>().WithConnection(connectionString);
    }
}

在此示例中,该AcccountServiceRegisty方法Initialize()将在应用程序的整个生命周期内调用一次,但ReInitialize()会随每个 WCF 服务请求调用。将ReInitialize()给出将执行的 WCF 操作的名称以及将提供的参数。完成后ReInitialize(),对服务实例进行最后一次 UnityBuildUp()调用,然后执行服务操作。

正如示例进一步说明的那样,有关服务调用的信息用于确定 DataAccess 实例将被实例化的数据库连接字符串。

为了创建这种行为,我最初计划为每个需要唯一绑定的请求创建一个 Unity 子容器。这就是ReInitialize()调用传入 childContainer 参数的原因。但后来我发现它CreateChildContainer本身似乎不是线程安全的。事实上,我发现很难找到任何 .net IOC 容器的线程安全声明(Autofac 除外,这使得它相当清楚)。

我怀疑允许线程安全注册的容器会使用ConcurrentDictionary不可变集合。走着瞧。

另一方面,如果我绝对必须避免这种动态的、多线程的注册过程——我想我会进行类型到委托的注册而不是类型到类型的注册。这样,委托可以动态决定要创建什么,而不是绑定本身是动态的。在这种情况下,前面的示例代码会将所有注册从ReInitialize()方法移动到Initialize()方法中,并且IDataAccessConfig实现将更改为如下所示:

public class DataAccessRegistry: UnityContainerExtension, IDataAccessConfig
{
    [ThreadStatic]
    string connection;

    protected override void Initialize()
    {
        Container.RegisterType<IDataAccess>(new InjectionFactory(c => new DataAccess(connection)));
    }

    public IDataAccessConfig WithConnection(string connection)
    {
        this.connection = connection;
        return this;
    }
}

上述示例的关键部分是[ThreadStatic]确保多个线程可以WithConnection()安全调用。

但这并没有改变我的问题——是否有一个具有线程安全注册的 .net 容器?

4

1 回答 1

0

编辑:

Autofac具有该功能

所有容器操作在多个线程之间使用都是安全的。

解析上下文对象是单线程的,除非在依赖解析操作过程中,否则不应使用。

容器层次结构机制通过维护任何工厂/容器组件的组件注册的本地副本来进一步减少锁定。完成初始注册副本后,使用“内部”容器的线程可以创建或访问此类组件,而不会阻塞任何其他线程。

您可以使用Autofac注册特定于线程的服务。

线程安全类型以下类型对于多个线程的并发访问是安全的:

容器

组件注册表

Disposer ( IDisposer的默认实现)

LifetimeScopeILifetimeScope的默认实现)

这些类型几乎涵盖了所有运行时/解决方案。

ContainerBuilder专为配置时的单线程访问而设计

于 2013-10-30T18:19:28.717 回答