在通用厂注册法StructureMap [英] Registering Method on Generic Factory with StructureMap
问题描述
我想使用一个通用的工厂类的方法在我的structuremap注册表。通常情况下,我会使用使用工厂方法在注册类型时注意以下事项:
I am trying to use a method on a generic factory class in my structuremap registry. Normally, i would use the following when registering a type using a factory method:
For<Foo>().Use(x => new FooFactory().GetFoo());
而注册一个泛型类型时注意以下事项:
And the following when registering a generic type:
For(typeof(ISomeGeneric<>)).Use(typeof(SomeGeneric<>));
我如何将二者结合起来,并检索从一个普通的工厂方法泛型类型?我想应该是这样的:
How can I combine the two and retrieve a generic type from a generic factory method? I think it should be something like:
For(typeof(IFoo<>)).Use(typeof(x => new FooFactory<>().Create(someParameter));
这只是给出了一个
"Cannot convert lambda expression to type object because it is not a delegate type"
错误。我已经试过各种组合,但我难住了。任何想法?
error. I've tried various combinations but am stumped. Any ideas?
谢谢。
推荐答案
这是可能的,但我会找一个选择,如果你可以的。问题是,与开放式泛型工作, 。你必须使用一些反思这意味着你将采取的性能损失。
This is possible, BUT I would look for an alternative if you can. The issue is that to work with the open generic, you have to use some reflection. This means you will take a performance hit.
public class FooRegistry:Registry
{
public FooRegistry()
{
For(typeof(IFoo<>)).Use(x =>
{
var ParamType = x.BuildStack.Current.RequestedType
.GetGenericArguments()[0];
return BuildUsingFooFactory(ParamType);
});
}
private object BuildUsingFooFactory(Type paramType)
{
var factoryType = typeof (FooFactory<>).MakeGenericType(new[] {paramType});
var createMethod = factoryType.GetMethod("Create");
object factory = Activator.CreateInstance(factoryType);
return createMethod.Invoke(factory, new[] {"SomeParameterString"});
}
}
public class FooFactory<T>
{
public IFoo<T> Create(string param)
{
return new Foo<T>();
}
}
public interface IFoo<T>
{
}
public class Foo<T> : IFoo<T>
{
}
你在做什么,以便为以下内容:
What you are doing in order is the following:
- 找到所请求的一般的参数是什么。 (ParamType)
- 创建一个非开放泛型类型的工厂(factoryType)
- 抢create方法关闭它。 (createMethod)
- 创建工厂使用Activator(工厂)
- 的实例,调用与您的一些参数工厂实例的创建方法。
- Find out what the requested generic argument is. (ParamType)
- Create a non-open generic type for the factory (factoryType)
- Grab the create method off of it. (createMethod)
- Create an instance of the factory using the Activator (factory)
- Call the create method on the factory instance with your some parameter.
StructureMap负责输出铸造右侧接口的。
StructureMap takes care of casting the output to the right interface.
更好的解决方案
而不是直接使用的IFoo的,使用IFooFactory。这使得它更干净,你有一个开放的通用映射到IFooFactory<>。然后只得到FooFactory你需要生成你的对象类型
Instead of using the IFoo directly, use the IFooFactory. This makes it much cleaner, you have an open generic mapping to the IFooFactory<>. Then just get the type of FooFactory you need to generate your objects.
public class FooRegistry:Registry
{
public FooRegistry()
{
For(typeof (IFooFactory<>))
.Use(typeof (FooFactory<>))
.CtorDependency<string>("connection")
.Is("SomeConnectionString");
}
}
public interface IFooFactory<T>
{
IFoo<T> CreateInstance();
}
public class FooFactory<T> : IFooFactory<T>
{
public FooFactory(string connection)
{
}
public IFoo<T> CreateInstance()
{
return new Foo<T>();
}
}
public interface IFoo<T>
{
}
public class Foo<T> : IFoo<T>
{
}
这篇关于在通用厂注册法StructureMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!