Autofac注册并解析实现通用接口的类型

时间:2011-08-08 10:43:58

标签: c# generics autofac covariance

我不知道如何陈述这个问题,因为我不确定问题所在。我认为它是一个基本的协方差问题,但解决方案可能在其他地方找到,可能是设计接口的方式,也可能是实现的注册方式。

无论如何,该示例试图注册实现通用接口的所有类型,然后使用泛型的类型解析类型。然后尝试将此类型转换为其基类型,以便能够在该实现上调用方法。

现在尝试施法时失败了。例如,第一行代码无法编译。删除后,程序在尝试强制执行的行上失败。

class Program
{
    private static IContainer _container;

    static void Main(string[] args)
    {
        // Is this the problem?
        IHandler<IConfiguration> test = new MyHandler();

        // setup ioc
        var builder = new ContainerBuilder();
        builder.RegisterAssemblyTypes(typeof(Program).Assembly)
            //.Where(t => typeof(IHandler<IConfiguration>).IsAssignableFrom(t));
            .Where(t => t.GetInterfaces()
                .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandler<>))
                .Any()
                )
            .As(t => t.GetInterfaces()
                .Where(i => i.GetGenericTypeDefinition() == typeof(IHandler<>))
                .Single()
            );
        _container = builder.Build();

        // get my configuration impl
        var configuration = new MyConfiguration();

        // resolve handler for the configuration
        var configurationType = configuration.GetType();
        var handlerGenericType = typeof(IHandler<>);
        var handlerType = handlerGenericType.MakeGenericType(configurationType);
        var handler = _container.Resolve(handlerType);
        var typedHandler = (IHandler<IConfiguration>) handler;

        // handle it!
        typedHandler.Handle(configuration);
    }
}

public interface IConfiguration
{
}

public interface IHandler<T> where T : IConfiguration
{
    void Handle(T myConfiguration);
}

public class MyConfiguration : IConfiguration
{
}

public class MyHandler : IHandler<MyConfiguration>
{
    public void Handle(MyConfiguration myConfiguration)
    {
        Console.WriteLine("Handling my stuff...");
    }
}

1 个答案:

答案 0 :(得分:2)

这无法发挥作用 原因如下:
IHandler<IConfiguration>需要IConfiguration作为Handle的参数 如果您的第一行有效,则会编译以下内容:

MyOtherConfiguration config = new MyOtherConfiguration();
IHandler<IConfiguration> test = new MyHandler();
test.Handle(config);

显然,这是不正确的,因为MyHandler.Handle需要MyConfiguration或派生类型。

如我在本答案的早期版本中所述使用反差方法,您可以执行以下操作:

IHandler<MyDerivedConfiguration> test = new MyHandler();

MyDerivedConfiguration来自MyConfiguration

相关问题