我有以下课程:
public interface IRenderer<T>
{
string Render(T obj);
}
public class Generic<T> { }
public class SampleGenericRenderer<T> : IRenderer<Generic<T>>
{
public string Render(Generic<T> obj)
{
throw new NotImplementedException();
}
}
我希望能够调用StructureMap
ObjectFactory.GetInstance<IRenderer<Generic<string>>>();
并获得SampleGenericRenderer<string>
。
我正在使用以下注册并在调用GetInstance时收到此错误。 “无法投射类型的对象:
ConsoleApplication1.SampleGenericRenderer'1 [ConsoleApplication1.Generic'1 [System.String]]” 输入 “ConsoleApplication1.IRenderer'1 [ConsoleApplication1.Generic'1 [System.String]。
public class CoreRegistry : Registry
{
public CoreRegistry()
{
Scan(assemblyScanner =>
{
assemblyScanner
.AssemblyContainingType(typeof(IRenderer<>));
assemblyScanner.AddAllTypesOf(typeof(IRenderer<>));
assemblyScanner
.ConnectImplementationsToTypesClosing(
typeof(IRenderer<>));
});
}
}
有没有办法配置StructureMap,以便创建SampleGenericRenderer<string>
而不是SampleGenericRenderer<Generic<string>>
?
更新:我最终自己为这个依赖项子集做了类型构造。因为它们将上下文绑定与许多不受支持的通用绑定相结合,所以这被证明是最干净的解决方案。
答案 0 :(得分:2)
正如Pete所解释的那样,StructureMap可能无法做到这一点。其他DI容器可能会取得更大的成功,但并非所有的容器都支持更复杂的通用技巧。唯一能让我知道的是Simple Injector。使用Simple Injector,您只需要以下配置:
var container = new Container();
container.Register(typeof(IRenderer<>), typeof(SampleGenericRenderer<>));
// Usage
var renderer = container.GetInstance<IRenderer<Generic<string>>>();
renderer.Render(new Generic<string>());
有关此方法的更多信息,请访问here。
答案 1 :(得分:1)
对我而言,这有效:
class Program
{
static void Main()
{
ObjectFactory.Configure(x=>x.AddRegistry<CoreRegistry>());
var instance = ObjectFactory.GetInstance(typeof(IRenderer<string>)) as IRenderer<Generic<string>>;
var render = instance.Render(new Generic<string>());
}
}
这会引发异常:
ObjectFactory.GetInstance<IRenderer<Generic<string>>>();
你真正的问题是什么?
编辑:
在某些情况下,这也可以起作用(如果您在设计时不知道Generic<string>
):
static void Main()
{
ObjectFactory.Configure(x => x.AddRegistry<CoreRegistry>());
var instance = ObjectFactory.GetInstance(typeof(IRenderer<string>));
var methodInfo = instance.GetType().GetMethod("Render");
methodInfo.Invoke(instance, new[] { new Generic<string>() });
}
答案 2 :(得分:1)
我不相信StructureMap有任何关闭内部泛型参数的机制。
这不理想,但您可以尝试创建自己的IRegistrationConvention
,每当遇到Generic<>
的封闭类型时,请执行以下操作:
var generic_t = typeof(Generic<>).MakeGenericType(type);
var sample_renderer_t = typeof(SampleGenericRenderer<>).MakeGenericType(type);
var renderer_t = typeof(IRenderer<>).MakeGenericType(generic_t);
graph.AddType(renderer_t, sample_renderer_t);
有关详细信息,请参阅http://docs.structuremap.net/ScanningAssemblies.htm#section11。