为解决Autofac中已注册的开放泛型提供代理

本文关键字:泛型 代理 Autofac 解决 注册 | 更新日期: 2023-09-27 18:00:34

我有一个这样的界面:

ICreator<T> {}

我想做的是让用户解决这样的依赖关系:

var creator = container.Resolve<ICreator<IUser>>();

诀窍是,我希望能够为ICreator<T>的具体类型进行一些自定义创建。在我的例子中,我有一个带有构造函数的Creator<T, TConcrete>,它采用了一个使用TConcrete的泛型类型。按照惯例,我知道TConcrete的类型应该是ICreator中定义的T,但RegisterGeneric似乎没有提供我所需要的,即创建Creator<,>实例的委托。

或者这确实存在于Autofac,而我却错过了它?任何见解都将不胜感激-TIA。

为解决Autofac中已注册的开放泛型提供代理

使用OnActivatingReplaceInstance是完成我需要的东西所必需的挂钩:

builder.RegisterGeneric(typeof(FakeCreator<>)).As(typeof(ICreator<>)).OnActivating(args =>
    {
        // ...
        args.ReplaceInstance(new Creator<...,...>());
    });

这并不完美,因为Autofac将创建配置的泛型类型的实例,但它可以工作。

您可以为具体类型注册特定的创建者。样品:

public interface ICreator<T>
{
    void WriteName();
}
public class Creator<T> : ICreator<T>
{
    public void WriteName()
    {
        Console.WriteLine("I'm standard creator: " + typeof(T).FullName);
    }
}
public class CustomIntCreator : ICreator<int>
{
    public void WriteName()
    {
        Console.WriteLine("I'm custom int creator");
    }
}
class Program
{
    static void Main(string[] args)
    {
        ContainerBuilder cb = new ContainerBuilder();
        cb.RegisterGeneric(typeof (Creator<>)).As(typeof (ICreator<>));
        cb.RegisterType<CustomIntCreator>().As<ICreator<int>>();
        var container = cb.Build();
        var intCreator = container.Resolve<ICreator<int>>();            
        var standardCreator = container.Resolve<ICreator<double>>(); 
        intCreator.WriteName(); //writes "I'm custom int creator"
        standardCreator.WriteName(); //writes "I'm standard creator: System.Double"
        Console.ReadLine();
    }
}