BrunoJuchli / StaticProxy.Fody

Creating proxies at compile time.
16 stars 3 forks source link

Interface Proxy with generic-Methods #12

Closed Fruchuxs closed 7 years ago

Fruchuxs commented 7 years ago

Hello, after some strange "TypeError"-Exceptions I figured out, that StaticProxy doesn't seems to support generic interface Methods like:

    [StaticProxy]
    public interface IBla
    {
        void DoIt<T>();
    }

Another use case which will also fail:

    [StaticProxy]
    public interface IBla
    {
        Task<T> DoIt<T>();
    }

Do you have any plans to implement this feature?

Greetings, Fruchuxs

BrunoJuchli commented 7 years ago

Dear Fruchuxs Yes, planned, but I was holding off until I got some feedback. Could you give me an example of what the interceptor would do and how it would ideally rely/access the generic type information? Basically, what kind of "interface" would make your job easiest?

An option is to do it the same way Castle.DynamicProxy is handling it (see IInvocation.cs. Other suggestions are welcome.

I currently have time to invest in open-source so I'm planning on having this done and ready in a few test. Would you be willing to check out a beta version?

Fruchuxs commented 7 years ago

My Idea was simply to automate "Proxy-Pattern-Instances". I just wanted to delegate the calls from the interceptor to the real implementation which is holded by the interceptor. The Intercept method looks like this:

public void Intercept(IInvocation invocation)
{
     invocation.ReturnValue = invocation.Method.Invoke(realInstance, invocation.GenericArguments);
}

I'm not an expert in C# reflections or in code weaving. But after I played a little bit around, I miss some properties in the IInvocation-interface like the proxy type or the target type (the type who is decorated by the StaticProxy-Annotation). Atm I reach the types e.g. with invocation.Method.DeclaringType. So I think the Castle.DynamicProcy.IInvocation-Interface is quite good, because it provides all possibilities.

Personally I would not make it too complicated. Just let the reflections be reflections:

public void Intercept(IInvocation invocation)
{
    if(invocation.Method.IsGenericMethod) { /* generic call */ } 
     else { /* normal call */ }
}

I'm not sure about the generic call. I think you need to put the specific generic type also in the IInvocation-Interface...

After I played a little bit around, it would be nice if you can deliver a more ... detailed documentation. I needed to dig around in your testcases to figure out how some things works.

Thank you for your quick response!

Greetings, Fruchuxs

Fruchuxs commented 7 years ago

Hello, I assume your time-investmend-window for open source has been closed. Maybe you can give me some hints how I can implement the Feature - but I don't promise anything. :)

BrunoJuchli commented 7 years ago

@Fruchuxs Actually it has been postponed. I haven't forgotten about it, but there was a pressing issue to attend to, sorry. If you want to take a peak, you're welcome, though it involves IL Code emitting... first you should start with the unit / integration tests, they don't require any "specific" knowledge on how things need to be actually implemented. I think I should have time to start the implementation, maybe even get it done, tomorrow. If not, I shall post be back with more information...

BrunoJuchli commented 7 years ago

@Fruchuxs I'm currently working on this but first wanted to migrate to VS2017 tooling. However, I've hit a small stumpling block with VS2017 csproj + Fody, which breaks fody-weaver search in the development scenario. Hence it's taking a bit longer than expected...

Fruchuxs commented 7 years ago

@BrunoJuchli Thank you for the info. This is just a nice to have feature for me, to generate a proxy automatically to increase the maintainability of my project for some units.

BrunoJuchli commented 7 years ago

@Fruchuxs Sure, I'm happy to work on this. The issue currently in play is https://github.com/dotnet/sdk/issues/1435

But I will do a local workaround to progress with development as soon as I'm done contributing towards fixing that issue.

BrunoJuchli commented 7 years ago

@Fruchuxs I've implemented support for generic methods (and -classes and -interfaces) and released "pre-release" nuget packages. PEverify tests, unit- and integration tests pass. So I'm fairly confident it works. I'd appreciate it if you could test it and give me feedback, though. If everything works as it should I'll release.

Note, that you'll need Fody 2.1+, plus a new Version of both StaticProxy.Fody and StaticProxy.Interceptor - there's a breaking change involved.

StaticProxy.Fody: 1.0.150-GenericMethods

StaticProxy.Interceptor: 1.0.127-GenericMethods -- depends on NetStandardLibrary 1.6 1.0.124-GenericMethods -- depends on NetStandardLibrary 1.6.1

--> for StaticProxy.Interceptor it would be nice if you could try out both versions. Per default VS/.net sdk references NetStandardLibrary 1.6.1, but 1.6.0 works just as fine in my tests... I'll release with 1.6.1 unless there's an issue with that.

Fruchuxs commented 7 years ago

Thank you for this! I'll check out this later.