我不知道如何陈述这个问题,因为我不确定问题所在。我认为它是一个基本的协方差问题,但解决方案可能在其他地方找到,可能是设计接口的方式,也可能是实现的注册方式。
无论如何,该示例试图注册实现通用接口的所有类型,然后使用泛型的类型解析类型。然后尝试将此类型转换为其基类型,以便能够在该实现上调用方法。
现在尝试施法时失败了。例如,第一行代码无法编译。删除后,程序在尝试强制执行的行上失败。
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...");
}
}
答案 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
。