我正在实现一个设计,我的图层将位于客户端和服务器之间,无论我从服务器获取什么对象,我都会将其包装在透明代理中并提供给客户端,这样我就可以跟踪对象中的更改内容,所以当保存它时,我只会发送更改的信息.
我查看了城堡动态代理,linfu,虽然他们可以生成代理类型,但他们不能接受现有的对象并换行.
想知道它是否可以使用这些框架,或者是否有任何其他框架可以实现这一点......
我开始使用Castle DynamicProxy,我有这个示例来跟踪对象属性的更改.
问题:
码:
class Program
{
static void Main(string[] args)
{
var p = new Person { Name = "Jay" }.AsTrackable();
//here's changed properties list should be empty.
var changedProperties = p.GetChangedProperties();
p.Name = "May";
//here's changed properties list should have one item.
changedProperties = p.GetChangedProperties();
}
}
public static class Ext
{
public static T AsTrackable<T>(this T instance) where T : class
{
return new ProxyGenerator().CreateClassProxyWithTarget
(
instance,
new PropertyChangeTrackingInterceptor()
);
}
public …
Run Code Online (Sandbox Code Playgroud) 我想为 BCL 中的类型创建动态代理,该类型是具有内部构造函数的抽象类。我一直是城堡的动态代理,这失败了,但有一个例外,指出没有无参数构造函数(它们是 - 它是内部的)。
有没有办法用城堡来实现这一目标?如果不是,其他任何动态代理框架都能够做到这一点吗?这是开发的开始,因此更改框架很容易。
我想要实现的是使用Castle Windsor拦截器的AOP属性.我已经取得了一些成功,但在课堂级别与方法级别方面遇到了问题.
所以鉴于此组件:
public interface IMyComponent
{
void ShouldBeInterceptedByStopWatch_AND_ExceptionLogger();
void ShouldBeInterceptedByExceptionLogger();
}
[LogExceptionAspect]
public class MyComponent : IMyComponent
{
[StopwatchAspect]
public void ShouldBeInterceptedByStopWatch_AND_ExceptionLogger()
{
for (var i = 0; i < 2; i++) Thread.Sleep(1000);
}
public void ShouldBeInterceptedByExceptionLogger()
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
我希望记录器方面可以拦截ShouldBeInterceptedByExceptionLogger()
但不会发生,除非我从其他方法中删除秒表方面,或从类中删除记录器方面并将其添加到ShouldBeInterceptedByExceptionLogger()
.但两者ShouldBeInterceptedByStopWatch_AND_ExceptionLogger()
都截获了.
整个示例应用程序可以在 - https://bitbucket.org/jayala/juggernet-aop找到
基本上它正在做的是使用一个工具来注册一个IContributeComponentModelConstruction
拦截器,如果它在类级别找到一个方面,或者如果它在方法级别找到方面,则添加一个拦截器+方法钩子.
这是我引导容器的方式:
var container = new WindsorContainer()
.AddFacility<LogExceptionAspectFacility>()
.AddFacility<StopwatchAspectFacility>()
.Register(Component
.For<IMyComponent>()
.ImplementedBy<MyComponent>()
.LifeStyle.Transient);
Run Code Online (Sandbox Code Playgroud)
设施正在做的是注册这样的拦截器和模型贡献者
public abstract class BaseAspectFacility<TAspectAttribute, TAspectInterceptor> : …
Run Code Online (Sandbox Code Playgroud) 我正在学习使用Ninject和Interceptor模式.
我有以下拦截器.
public class MyInterceptor:IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Pre Execute: " + invocation.Request.Method.Name);
foreach (var param in invocation.Request.Arguments)
{
Console.WriteLine("param : " + param);
}
invocation.Proceed();
Console.WriteLine("Post Execute: " + invocation.Request.Method.Name);
Console.WriteLine("Returned: " + invocation.ReturnValue);
}
}
Run Code Online (Sandbox Code Playgroud)
并且有一个名为MyClass
只有2个简单方法的类,虚拟允许拦截器处理它们.(两种方法是Echo和double,这就像他们的名字所说的那样.)
我通过NuGet将Ninject,Ninject.Extensions.Interception和Ninject.Extensions.Interception.DynamicProxy添加到我的项目中.
添加以下using
声明.
using Ninject;
using Ninject.Extensions.Interception.Infrastructure.Language;
using Ninject.Extensions.Interception;
Run Code Online (Sandbox Code Playgroud)
我的Main方法,它执行引导看起来像这样.
static void Main(string[] args)
{
MyClass o = null;
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<MyClass>().ToSelf().Intercept().With(new MyInterceptor());
o = kernel.Get<MyClass>();
}
o.Echo("Hello World!"); // Error …
Run Code Online (Sandbox Code Playgroud) c# ninject castle-dynamicproxy ninject-extensions ninject-interception
我有这样的场景:
我正在使用拦截器来捕获对主程序引用的程序集内部类(我们称之为Feature)的类的调用.装配特征由NuGet安装(它不是公共的,而是我们的内部装配)并且引用了另一个装配(让我们称之为Core).主项目也引用了汇编Core.Core包含类定义,该类定义用作截取方法之一的参数类型.
只要主项目和功能引用相同版本的Core库,一切正常.当此版本不同并且截获的方法使用Core中的类型作为方法参数时出现问题.
在这种情况下,会抛出一个异常A strongly-named assembly is required.
:
[FileLoadException: Could not load file or assembly 'Core, Version=0.2.2.30, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)]
Castle.Proxies.Invocations.IBasketService_Update.InvokeMethodOnTarget() +0
Castle.DynamicProxy.AbstractInvocation.Proceed() +116
Project.Basket.BasketServiceUpdatedInterceptor.Intercept(IInvocation invocation) in c:\(...)\Basket\BasketServiceUpdatedInterceptor.cs:20
Castle.DynamicProxy.AbstractInvocation.Proceed() +604
Castle.Proxies.IBasketServiceProxy.Update(ProductId productId, UInt16 quantity) +210 (...)
Run Code Online (Sandbox Code Playgroud)
Where version of Core 0.2.2.30 is a version that assembly Feature is expecting, main project is using for example version 0.2.2.31. Castle DynamicProxy is not able to find Core …
我正在使用大量未记录的 Castle 动态代理系统。我已经设法让它做我想做的几乎所有事情,除了一件事:如何让代理方法抛出异常而不是返回值?
public sealed class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (CheckArgs(invocation.Arguments))
{
invocation.ReturnValue = DoRealWork(invocation.Arguments);
}
else
{
invocation.Exception = new InvalidOperationException(); // How?
}
}
}
Run Code Online (Sandbox Code Playgroud) 我们基本上有一个如下所示的类,它使用Castle.DynamicProxy进行拦截.
using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Castle.DynamicProxy;
namespace SaaS.Core.IoC
{
public abstract class AsyncInterceptor : IInterceptor
{
private readonly ILog _logger;
private readonly ConcurrentDictionary<Type, Func<Task, IInvocation, Task>> wrapperCreators =
new ConcurrentDictionary<Type, Func<Task, IInvocation, Task>>();
protected AsyncInterceptor(ILog logger)
{
_logger = logger;
}
void IInterceptor.Intercept(IInvocation invocation)
{
if (!typeof(Task).IsAssignableFrom(invocation.Method.ReturnType))
{
InterceptSync(invocation);
return;
}
try
{
CheckCurrentSyncronizationContext();
var method = invocation.Method;
if ((method != null) && typeof(Task).IsAssignableFrom(method.ReturnType))
{
var taskWrapper = GetWrapperCreator(method.ReturnType);
Task.Factory.StartNew(
async () => …
Run Code Online (Sandbox Code Playgroud) 前段时间我发布了一个开源库,它严重依赖Castle DynamicProxy。现在 .NET Core 1.x RTM 出来了,我不知道如何支持 .NET Core(Castle DynamicProxy 仍然不能在 .NET Core 上工作......),直到我遇到了DispatchProxy
class。
实际上没有关于整个类的全面文档,与Castle DynamicProxy相比,它似乎太有限了。
就我而言,我需要拦截属性设置器,并在运行时在生成的代理中实现一些接口。
是否DispatchProxy
满足这些要求?或者,在 .NET Core 上运行时生成代理的替代方法是什么?
我想在程序集级别替换一个类,以便所有引用都调用新的实现。可以说我在整个项目中的程序集中使用了通用类,例如
System.Generic.Collections.List
我的项目也引用了其他依赖的程序集List
。
现在假设我想使用我的版本“ List
Whereever this is called”。
var values = new List<int> { 1, 2, 3, 4, 5 }
Run Code Online (Sandbox Code Playgroud)
如何在程序集级别替换类,以便我不必更新代码中的任何引用,或者可以在单个位置完成它。
我记得有元数据伙伴类和类似的东西是否可以使用全局编译指示进行覆盖?我依稀记得使用这样的语法:System.Generic.Collections.List::MyAssembly.List
我想以一种duck-typed
底层类不必继承原始类的方式替换它,但我应该以相同的方式公开所有方法
注意:我需要以全局方式解决这个问题,通过反射或配置的单个入口点。
我过去已经做过动态替换方法的事情,请参阅:Dynamically Append Code to a method .Net-Core