在Autofac / c#中的方法中作为参数传递时的解析类型(请检查示例代码)

时间:2018-09-18 21:40:44

标签: c# autofac

我在.Net Core 2.1应用程序中使用Autofac。我有一个类,该类的方法可以使用new关键字直接实例化类型,因此它与特定的实现相关。如何使用Autofac而不是new来解析类型?该方法创建一个Engine类型的对象,并将其添加到IEngine类型的集合中,在该集合中Engine实现了IEngine。因此,构造函数或方法解析将无法正常工作。

下面是示例代码:

public class Vehicle<T1> : IVehicle<T1>
{
    private Dictionary<string, IEngine<T>> Engines = new Dictionary<string, IEngine<T>>();

    public void Create(string id)
    {
        IEngine<T> engine = new Engine<T>();

        // use engine...

        Engines.Add(id, engine);
    }
}

如您所见,Vehicle与IEngine的实现紧密相连。在这种情况下,如何使用Autofac动态解析IEngine?我认为我的问题是我没有对Autofac容器的引用。如何在这样的类中获得对容器的引用?

2 个答案:

答案 0 :(得分:0)

我认为最好将Engine对象的实例化委托给另一个类(例如Factory)来帮助您将IEngine解析为所需的具体引擎类。

此外,您还可以在此处使用事件,因此,这里的Create方法是需要引擎的触发器,在其他类上,可以通过事件/委托解析并传递给引擎。

答案 1 :(得分:0)

这里是一个如何在Autofac中使用自动生成的委托工厂实例化引擎的示例。您会看到,Autofac能够自动执行此操作:

public class Program
{
    public static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.RegisterGeneric(typeof(Vehicle<>)).As(typeof(IVehicle<>));
        builder.RegisterGeneric(typeof(Engine<>)).As(typeof(IEngine<>));
        var container = builder.Build();

        var vehicle = container.Resolve<IVehicle<object>>();
        vehicle.Create("1");

        Console.WriteLine(vehicle.EngineCount);
        Console.ReadKey();
    }
}

public interface IVehicle<T>
{
    void Create(string id);

    /// <summary>
    /// This property is just for testing
    /// </summary>
    int EngineCount { get; }
}

public class Vehicle<T> : IVehicle<T>
{
    private readonly Func<IEngine<T>> _engineFactory;
    private Dictionary<string, IEngine<T>> Engines = new Dictionary<string, IEngine<T>>();

    /// <summary>
    /// This property is just for testing
    /// </summary>
    public int EngineCount => Engines.Count;

    public Vehicle(Func<IEngine<T>> engineFactory)
    {
        _engineFactory = engineFactory;
    }

    public void Create(string id)
    {
        IEngine<T> engine = _engineFactory();

        // use engine...

        Engines.Add(id, engine);
    }
}

public interface IEngine<T>
{
}

public class Engine<T> : IEngine<T>
{
}

请注意,我已将类型Vehicle<>中的泛型类型参数的名称从T1更改为T,以使其与类型参数相对应,该类型参数在内部使用Engine<T>实例的类。希望对您有所帮助。