询问者
c# dynamic相关的一个神奇问题

问题
-
自己简单实现的aop功能如果代理类放到控制台项目里是可以成功运行的,放到别的类库里是不能成功的,报错 'System.ValueType' does not contain a definition for 'GetAwaiter'。代码见github https://github.com/wangronghua/DynamicIssue
master分支是报错的,ok分支是好的,区别就是把代理类移到了控制台项目里。这里也贴下代码。
控制台类库class Program { static async Task Main(string[] args) { var items = (await ProxyDecorator2<IPersonService, PersonService>.Create().GetPartAsync(x => new { x.ID, x.Name }, x => x.ID == 1)); foreach (var item in items) { Console.WriteLine(item.ID); Console.WriteLine(item.Name); } Console.WriteLine("结束"); } }
第二个类库
public class PersonService: IPersonService { public ValueTask<List<TResult>> GetPartAsync<TResult>(Func<Person, TResult> selresult, Func<Person, bool> predicate) { return new ValueTask<List<TResult>>(dataSource.Where(predicate).Select(selresult).ToList()); } private static List<Person> dataSource=new List<Person> { new Person{ ID = 1,Name = "张三"}, new Person{ ID = 2,Name = "李四"} }; } public interface IPersonService { ValueTask<List<TResult>> GetPartAsync<TResult>(Func<Person, TResult> selresult, Func<Person, bool> predicate); } public class Person { public int ID { get; set; } public string Name { get; set; } } public class ProxyDecorator2<T, TClass> : DispatchProxy where T : class where TClass : T, new() { protected T _decorated; public static T Create() { var proxy = Create<T, ProxyDecorator2<T, TClass>>(); var proxyReal = proxy as ProxyDecorator2<T, TClass>; if (proxyReal == null) throw new Exception("proxyReal报错"); proxyReal._decorated = new TClass(); return proxy; } private async Task<object> InvokeCoore(MethodInfo targetMethod, object[] args) { dynamic dy = targetMethod.Invoke(_decorated, args); var x = await dy; return dy; } protected override object Invoke(MethodInfo targetMethod, object[] args) { return InvokeCoore(targetMethod, args).Result; } }
把 ProxyDecorator2 移到控制台类库里就能正常运行。
全部回复
-
Hi,
我重现了您的问题,我建议你可以做出以下更改。
把下面的代码替换到相应的地方。
private Task<object> InvokeCoore(MethodInfo targetMethod, object[] args) { var dy = targetMethod.Invoke(_decorated, args); return Task.FromResult(dy); }
Best Regards,
Jack
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com. -
我这边有个需求需要实现事务注入,完整的是这样的,所以需要await任务
private async Task<object> InvokeCoore(MethodInfo targetMethod, object[] args) { dynamic dy = targetMethod.Invoke(_decorated, args); var x = await dy; return dy; } protected override object Invoke(MethodInfo targetMethod, object[] args) { //开启事务 var result = InvokeCoore(targetMethod, args).Result; //提交事务 return result; }
如果不await的话业务代码还没执行完就执行提交事务操作了,这样就有问题了。或者我这个需求有什么好的解决方案? -
Hi
感谢您的反馈。
如果你想要设置await来执行方法,你可以参照以下方法。
private async Task<object> InvokeCoore(MethodInfo targetMethod, object[] args) { object dy = null ; await Task.Run(()=> { dy = targetMethod.Invoke(_decorated, args); }); return dy; }
Best Regards,
Jack
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com. -
Hi
你的意思是你还需要对 Invoke方法进行事务注入吗?
Best Regards,
Jack
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com. -
是的,这个是事务注入的通用方法,代码类似这种的。
private async Task<object> InvokeCoore(MethodInfo targetMethod, object[] args) { dynamic dy = targetMethod.Invoke(_decorated, args); var x = await dy; return dy; } protected override object Invoke(MethodInfo targetMethod, object[] args) { using(var transactionScope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted })){ var result = InvokeCoore(targetMethod, args).Result; transactionScope.Complete(); return result; } }
-
Hi
你上传的图片我看不了,我不太明确你当前的问题出在了哪里。请尝试重新上传图片。
Best Regards,
Jack
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.