我想發出一個返回Func <>的方法。在這個方法裏面,我必須創建一個委託或lambda表達式,它精確地爲返回類型提供服務。如何發出委託或lambda表達式
總之它應該是這樣的:
// I have a resolve method that will be called inside my missing method
// This is it's signature:
object Resolve(params object[] args);
// This is how I use it:
var barFactory = (Func<IBar>)MissingMethod(typeof(IBar));
var bar = barFactory.Invoke();
// or - with one string argument:
var fooFactory = (Func<string, IFoo>)MissingMethod(typeof(IFoo), typeof(string));
var foo = fooFactory.Invoke("argument for foo");
的MissingMethod()內它應該看起來像:
object MissingMethod(Type returnType, params Type[] argTypes)
{
// Create the type of Func<> based on the passed returnType and the argTypes
var funcType = typeof(Func<,...,>).MakeGenericType(...)
// Here I have to use the Resolve() method and cast the lambda to the correct type
return (cast to funcType)((arg1, arg2) => Resolve(arg1, arg2));
}
我認爲,只有這樣,才能讓我的MissingMethod()是,以使用reflection.emit。
你知道有關發射lambda或委託的好資源或教程嗎?
您是否看到另一個解決此問題的解決方案?
編輯:
這裏是什麼,我想才達到一個情景:
static void Main()
{
var container = new Container();
container.Register<Foo>();
container.Register<ConsumerClass>();
var consumerClass = Container.Resolve<ConsumerClass>();
}
class Foo()
{
public Foo(string argument) {}
}
class ConsumerClass
{
public ConsumerClass([Inject] Func<string, Foo> factory)
{
var foo1 = factory.Invoke("first foo");
var foo2 = factory.Invoke("another foo");
// ...
}
}
我想實現容器和決心()方法。我知道有一個「Foo」類型註冊。我知道它的構造函數需要一個字符串來調用。
當我必須解析「ConsumerClass」類型時,我發現它想要注入一個Func。這不正是我的容器可以提供,因爲通常它提供單instaces到美孚這樣的:
Container.Resolve<Foo>("argument");
但儘管如此容器應能提供函數求了。它具有所需的所有信息。
但是現在我被困在創建這個綁定的Func <,>中。並記住它也可能是Func < ,,,>。所以我正在尋找一種可以即時創建我的代表的解決方案。他們必須可以澆注到確切的綁定類型。
編輯:
我不知道該怎麼形容好...我試圖做類似this。但我不想通過一個目標。取而代之的
delegate void object LateBoundMethod(object target, object[] arguments);
我代表應該像
delegate void object LateBoundMethod(object[] arguments);
,目標是作爲一個實例字段。通過服用和改進Marc的解決方案,我得到:
private Delegate CreateDelegate(Type returnType, Type[] parameterTypes)
{
m_Type = returnType;
var i = 0;
var param = Array.ConvertAll(parameterTypes, arg => Expression.Parameter(arg, "arg" + i++));
var asObj = Array.ConvertAll(param, p => Expression.Convert(p, typeof(object)));
var argsArray = Expression.NewArrayInit(typeof(object), asObj);
var callEx = Expression.Call(null, typeof(FuncFactory).GetMethod("Resolve"), argsArray);
var body = Expression.Convert(callEx, returnType);
var ret = Expression.Lambda(body, param).Compile();
return ret;
}
private readonly Container m_Container;
private Type m_Type;
public object Resolve(params object[] args)
{
return m_Container.Resolve(m_Type, args);
}
但這是不完整的。 Resolve() - 方法不再是靜態的(因爲它需要兩個實例字段)並且不能被調用。所以這裏的問題是
var callEx = Expression.Call(null, typeof(FuncFactory).GetMethod("Resolve"), argsArray);
而不是作爲第一個參數傳遞null我認爲我需要對'this'的引用。我怎麼做?
我得說我不知道我得到的是什麼,你現在要做的,但會使得MissingMethod方法一般不是100%讓你解決問題的一半?或者這不是一個選擇? – kastermester 2009-06-02 14:48:21
另外,我確實得到這樣一個事實:爲了覆蓋所有可能的Func <>泛型,您必須多次編寫代碼,但正如Marc所說,您必須以任何方式對其進行硬編碼。 – kastermester 2009-06-02 14:49:37