在.NET 4.0中动态实现接口(C#)

时间:2022-09-02 12:01:36

With the new dynamic capabilities in .NET 4.0, it seems like it should be possible to dynamically implement an interface, e.g. given:

使用.NET 4.0中的新动态功能,似乎应该可以动态地实现接口,例如,给定:

public interface IFoo 
{
    string Bar(int baz);
}

public class Foo : IFoo
{
    public string Bar(int baz) { return baz.ToString(); }
}

public class Proxy : IDynamicMetaObjectProvider
{
    private readonly object target;

    public Proxy(object target) { this.target = target; }

    // something clever goes here
}

Then I'm hoping there is some way to make it possible to write:

然后我希望有一些方法可以写:

dynamic proxy = new Proxy(new Foo());
IFoo fooProxy = (IFoo)proxy; // because the target object implements it
string bar = fooProxy.Bar(123); // delegates through to the target implementation

But, as yet, I'm unsure what to replace // something clever goes here with.

但是,到目前为止,我还不确定要替换什么//这里有一些聪明的东西。

So, my questions are:

所以,我的问题是:

  1. Is this actually possible to do with the dynamic runtime? It appears that dynamically implementing things like methods and properties is fairly easy, but I haven't found any documentation about dynamically implementing interfaces and conversions to them.

    这实际上可以用动态运行时吗?似乎动态实现方法和属性之类的东西相当容易,但我没有找到任何关于动态实现接口和转换的文档。

  2. Assuming this is possible, how difficult is it likely to be? (You can assume I'm a decent programmer with plenty of experience of things like reflection, but new to the dynamic framework.)

    假设这是可能的,它有多难? (你可以假设我是一个体面的程序员,有很多反思之类的经验,但对动态框架来说是新手。)

  3. Are there any resources which would help to point me in the right direction for implementing something like this? Or even samples where this kind of thing has already been done that I can use as a starting point?

    是否有任何资源可以帮助我指出实现这样的事情的正确方向?或者甚至已经完成这种事情的样本我可以用作起点?

5 个解决方案

#1


13  

As far as I know, it's not possible without manual intervention to write or generate code that forwards the interface members to the wrapped instance. If you would like to see Microsoft-provided support for this sort of thing, you might want to consider voting at https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member .

据我所知,如果没有手动干预,编写或生成将接口成员转发到包装实例的代码是不可能的。如果您希望看到Microsoft提供的此类支持,您可以考虑通过https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface进行投票。 -implementation-via-implementation-member。

#2


39  

The opensource framework Impromptu-Interface was designed to do this. It generates a cached lightweight proxy with a static interface and uses the dlr to forward the invocation to the original object.

开源框架Impromptu-Interface旨在实现这一目标。它使用静态接口生成缓存的轻量级代理,并使用dlr将调用转发到原始对象。

using ImpromptuInterface;

public interface ISimpeleClassProps
{
    string Prop1 { get;  }

    long Prop2 { get; }

    Guid Prop3 { get; }
}

-

-

dynamic tOriginal= new ExpandoObject();
tOriginal.Prop1 = "Test";
tOriginal.Prop2 = 42L;
tOriginal.Prop3 = Guid.NewGuid();

ISimpeleClassProps tActsLike = Impromptu.ActLike(tOriginal);

#3


7  

I think I wrote a library that does what you want... It is called DynamicWrapper (on CodePlex) and it will automatically wrap a a class so it implements an interface. Is this what you want?

我想我写了一个你想要的库...它叫做DynamicWrapper(在CodePlex上),它会自动换一个类,所以它实现了一个接口。这是你想要的吗?

#4


3  

Explicit casting, as, and is fail because of type comparison would against your proxy base class, but implicit cast can trigger DynamicObject.TryConvert, such that you can then return inner object in-lieu of the dynamic object.
- TryConvert MSDN Documentation

显式转换as,因为类型比较而失败会对你的代理基类产生影响,但隐式转换可以触发DynamicObject.TryConvert,这样你就可以返回内部对象代替动态对象。 - TryConvert MSDN文档

While the code below works, this isn't interface delegation per se, only exposure of internal state. It sounds like you might be looking for something like an interception pattern such as Brian's DynamicWrapper.

虽然下面的代码有效,但这不是接口委托本身,只是内部状态的暴露。听起来你可能正在寻找类似拦截模式的东西,比如Brian的DynamicWrapper。

dynamic wrapper = new Proxy(new Foo());
IFoo foo = wrapper;
foo.Bar();

class Proxy : DynamicObject
{
    ...

    public override bool TryConvert(ConvertBinder binder, out object result)
    {
        Type bindingType = binder.Type;
        if (bindingType.IsInstanceOfType(target))
        {
            result = target;
            return true;
        }
        result = null;
        return false;

    }

}

#5


2  

Complementing the answer from @jbtule I have created my CustomActivator that is able to create a dynamic object at runtime and make it implements a desired interface. I also use the Impromptu-Interface framework to accomplish that.

补充@jbtule的答案我创建了我的CustomActivator,它能够在运行时创建一个动态对象并使其实现所需的接口。我还使用Impromptu-Interface框架来实现这一目标。

The call is simple:

电话很简单:

CustomActivator.CreateInstance<MyInterface>();

I put it on github.

我把它放在github上。

#1


13  

As far as I know, it's not possible without manual intervention to write or generate code that forwards the interface members to the wrapped instance. If you would like to see Microsoft-provided support for this sort of thing, you might want to consider voting at https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member .

据我所知,如果没有手动干预,编写或生成将接口成员转发到包装实例的代码是不可能的。如果您希望看到Microsoft提供的此类支持,您可以考虑通过https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface进行投票。 -implementation-via-implementation-member。

#2


39  

The opensource framework Impromptu-Interface was designed to do this. It generates a cached lightweight proxy with a static interface and uses the dlr to forward the invocation to the original object.

开源框架Impromptu-Interface旨在实现这一目标。它使用静态接口生成缓存的轻量级代理,并使用dlr将调用转发到原始对象。

using ImpromptuInterface;

public interface ISimpeleClassProps
{
    string Prop1 { get;  }

    long Prop2 { get; }

    Guid Prop3 { get; }
}

-

-

dynamic tOriginal= new ExpandoObject();
tOriginal.Prop1 = "Test";
tOriginal.Prop2 = 42L;
tOriginal.Prop3 = Guid.NewGuid();

ISimpeleClassProps tActsLike = Impromptu.ActLike(tOriginal);

#3


7  

I think I wrote a library that does what you want... It is called DynamicWrapper (on CodePlex) and it will automatically wrap a a class so it implements an interface. Is this what you want?

我想我写了一个你想要的库...它叫做DynamicWrapper(在CodePlex上),它会自动换一个类,所以它实现了一个接口。这是你想要的吗?

#4


3  

Explicit casting, as, and is fail because of type comparison would against your proxy base class, but implicit cast can trigger DynamicObject.TryConvert, such that you can then return inner object in-lieu of the dynamic object.
- TryConvert MSDN Documentation

显式转换as,因为类型比较而失败会对你的代理基类产生影响,但隐式转换可以触发DynamicObject.TryConvert,这样你就可以返回内部对象代替动态对象。 - TryConvert MSDN文档

While the code below works, this isn't interface delegation per se, only exposure of internal state. It sounds like you might be looking for something like an interception pattern such as Brian's DynamicWrapper.

虽然下面的代码有效,但这不是接口委托本身,只是内部状态的暴露。听起来你可能正在寻找类似拦截模式的东西,比如Brian的DynamicWrapper。

dynamic wrapper = new Proxy(new Foo());
IFoo foo = wrapper;
foo.Bar();

class Proxy : DynamicObject
{
    ...

    public override bool TryConvert(ConvertBinder binder, out object result)
    {
        Type bindingType = binder.Type;
        if (bindingType.IsInstanceOfType(target))
        {
            result = target;
            return true;
        }
        result = null;
        return false;

    }

}

#5


2  

Complementing the answer from @jbtule I have created my CustomActivator that is able to create a dynamic object at runtime and make it implements a desired interface. I also use the Impromptu-Interface framework to accomplish that.

补充@jbtule的答案我创建了我的CustomActivator,它能够在运行时创建一个动态对象并使其实现所需的接口。我还使用Impromptu-Interface框架来实现这一目标。

The call is simple:

电话很简单:

CustomActivator.CreateInstance<MyInterface>();

I put it on github.

我把它放在github上。