如何在IocManager中为Aspnet样板中的不同构造函数参数集注册类的Singleton

问题描述

我有一个Aspnet样板C#Web应用程序,在模块的PreInitialize()方法中,我有此依赖项注册

IocManager.Register<IMyProvider,MyConcreteProvider>(DependencyLifeStyle.Transient);

MyConcreteProvider类具有一个构造函数,当我解析IMyProvider接口时,可以使用该构造函数传递一个参数。我需要这样做,因为MyConcreteProvider的行为取决于传递的参数值。

using (var providerdisposable = IocResolver.ResolveAsdisposable<IMyProvider>(providerInstance,new
{
  param = "Test"
}))
{
  // Use providerInstance
}

它很好用,但是在IMyProvider接口的每个实例中,都重新创建了MyConcreteProvider类。我想拥有一个基于MyConcreteProvider参数值的param的Singleton,因此,如果我实例化MyConcreteProvider类的两次,并且两次都通过相同的值“ Test”到param参数中,它只实例化一次。

问题是,如何向IocManager注册类的单例以获取构造函数参数的不同值?

解决方法

实施基于param的自定义范围。

public override void PreInitialize()
{
    base.PreInitialize();

    IocManager.IocContainer.Register(
        Component.For<IMyProvider>().ImplementedBy<MyConcreteProvider>()
            .LifestyleScoped<MyProviderScopeAccessor>()
    );
}
public class MyProviderScopeAccessor : IScopeAccessor
{
    private static readonly ConcurrentDictionary<string,ILifetimeScope> collection = new ConcurrentDictionary<string,ILifetimeScope>();

    public ILifetimeScope GetScope(CreationContext context)
    {
        var param = (string)context.AdditionalArguments["param"];
        return collection.GetOrAdd(param,new DefaultLifetimeScope());
    }

    public void Dispose()
    {
        foreach (var scope in collection)
        {
            scope.Value.Dispose();
        }
        collection.Clear();
    }
}

参考:

  1. https://riptutorial.com/castle-windsor/example/25168/custom-lifestyle---iscopeaccessor
  2. https://github.com/castleproject/Windsor/blob/master/docs/implementing-custom-scope.md

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...