我希望能够发出一个返回Func<>类型的方法。在这个方法内部,我必须创建一个代理或者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或delegate的好资源或教程吗?
您是否看到此问题的另一个可能解决方案?
编辑:
这里是我想要实现的场景:
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" );
// ...
}
}
我正在尝试实现容器和Resolve()方法。我知道已经注册了“Foo”类型。我知道它的构造函数需要一个字符串来调用。
当我需要解析类型“ConsumerClass”时,我发现它想要注入一个Func。这不是我的容器可以提供的,因为通常它会像这样提供单个实例到Foo:
Container.Resolve<Foo>( "argument" );
然而,容器也应该能够提供一个 Func。它拥有所有所需的信息。
但现在我卡在了创建这个绑定的 Func<,> 上。请记住它也可能是一个 Func<,,,>。因此,我正在寻找一种可以动态创建我的委托的解决方案。它们必须能够强制转换为确切的绑定类型。
编辑:
我不确定如何更好地描述它... 我正在尝试做类似于这样的事情。但我不想传递一个目标。
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 );
我认为我需要一个指向'this'的引用,而不是将null作为第一个参数传递。 我该怎么做?