2881099/FreeSql.DynamicProxy

对于异步操作,没有返回值的方法,会有异常

luoyunchong opened this issue · 9 comments

AspNetCore Startup.cs中增加如下语句。

[Custom]
public virtual async Task CreateKeyAsync(CustomDto customDto)
{
       await Task.FromResult("");
        Console.WriteLine($"CustomRepository.CreateAsync({customDto.Key}) value");
}

DynamicProxyExtensions.cs
捕获

好的,未处理 Task 的情况,Task<object> 有处理

internal static Type ReturnTypeWithoutTask(this Type that)
{
    if (that.IsTask() == false) return that;
    return that.GetGenericArguments().FirstOrDefault() ?? typeof(void);
}

补上 ?? typeof(void); 正常了

这个动态代理其实和 FreeSql 没关系,实在想不出名字了就这样一取。

市面上动态代理库比较多,都比较好用。

这个库实现方式较简单,相信都能看懂源码,建议把源码放到项目中直接使用,方便调试。

fsql.Aop.TraceBefore += (_, e) => Trace.WriteLine($"----TraceBefore---{e.Identifier} {e.Operation}");
fsql.Aop.TraceAfter += (_, e) => Trace.WriteLine($"----TraceAfter---{e.Identifier} {e.Operation} {e.Remark} {e.Exception?.Message} {e.ElapsedMilliseconds}ms");

这两个可以监视到 UnitOfWork 事件

----TraceBefore---26cfe6a7-ec76-45d3-b5de-5ca4ec9e9147 UnitOfWork
----TraceBefore---43f2329d-eaed-47ea-b633-53c4b32327c3 BeginTransaction
INSERT INTO "Song"("Title") VALUES(NULL); SELECT last_insert_rowid();
INSERT INTO "Detail"("SongId", "Title") VALUES(0, NULL); SELECT last_insert_rowid();
INSERT INTO "Song"("Title") VALUES(NULL); SELECT last_insert_rowid();
----TraceAfter---43f2329d-eaed-47ea-b633-53c4b32327c3 BeginTransaction 提交  14ms
----TraceAfter---26cfe6a7-ec76-45d3-b5de-5ca4ec9e9147 UnitOfWork 释放  17ms

好的。我看那个demo用的这个,然后写了一样的代码发下,方法拦截不了,把一些方法排除后,能正常拦截,对比下发现了问题。。

image

QuickStart,当把某个方法 改成不是virtual,其他的virtual方法,也不会执行Cache2Attribute标签下的Before方法,即导致所有的拦截都是失效的。

如果用 ioc 是基于接口类型来注入的话,可以不加 virtual。

MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass().ToDynamicProxy();
IMyClass mc3 = new MyClass().ToDynamicProxy();

mc3 应该能生效,mc2 不可以(必须要加 virtual 重写才能生效)

是这样的,一个普通的类,没有加virtual,却加了上面的特性标签,在这个类的其他带有virtual的方法有特性标签却是失效的。

明白了,已修改