首页 > 解决方案 > 如何使用 IocManager 为 Aspnet 样板中的不同构造函数参数集注册类的单例

问题描述

我有一个 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为不同的构造函数参数值注册一个类的单例?

标签: c#aspnetboilerplate

解决方案


实现基于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

推荐阅读