C# 使用带有动态代理的Autofac自动输出消息 公共接口ILog { 无效写入(字符串消息); } 公共类MyLog:ILog { 公共无效写入(字符串消息) { 控制台写入线(msg); } } 公共接口日志 { ILog日志{get;set;} } 公共接口IMyClass { 无效试验(); } 公共类MyClass:IMyClass,ICanLog { 公共ILog日志{get;set;} 公开无效测试() { 日志写入(“测试”); } }

C# 使用带有动态代理的Autofac自动输出消息 公共接口ILog { 无效写入(字符串消息); } 公共类MyLog:ILog { 公共无效写入(字符串消息) { 控制台写入线(msg); } } 公共接口日志 { ILog日志{get;set;} } 公共接口IMyClass { 无效试验(); } 公共类MyClass:IMyClass,ICanLog { 公共ILog日志{get;set;} 公开无效测试() { 日志写入(“测试”); } },c#,inversion-of-control,autofac,ioc-container,castle-dynamicproxy,C#,Inversion Of Control,Autofac,Ioc Container,Castle Dynamicproxy,我用的是, 并尝试让MyClass测试方法自动输出“开始”/“结束” public class MyLogInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("BEGIN"); invocation.Proceed(); Console.WriteLine("END"); } } 以下是

我用的是, 并尝试让MyClass测试方法自动输出“开始”/“结束”

public class MyLogInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("BEGIN");
        invocation.Proceed();
        Console.WriteLine("END");
    }
}
以下是测试代码:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<MyLog>().As<ILog>();
builder.Register(c =>
{
    ProxyGenerator g = new ProxyGenerator();
    object proxy = g.CreateClassProxy(typeof(MyClass), new MyLogInterceptor());
    ICanLog proxyICanLog = (ICanLog)proxy;
    proxyICanLog.Log = c.Resolve<ILog>();
    return proxy;
}).As<IMyClass>();

using (var container = builder.Build())
{
    objectContext.Container = container;
    IMyClass myclass = container.Resolve<IMyClass>();
    myclass.Test();
}
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<MyLog>().As<ILog>();
builder.RegisterModule(new AutoLogModule());
builder.Register(c =>
{
    ProxyGenerator g = new ProxyGenerator();
    object proxy = g.CreateClassProxy(typeof(MyClass), new MyLogInterceptor());
    //ICanLog proxyICanLog = (ICanLog)proxy;
    //proxyICanLog.Log = c.Resolve<ILog>();
    return proxy;
}).As<IMyClass>();

using (var container = builder.Build())
{
    objectContext.Container = container;
    IMyClass myclass = container.Resolve<IMyClass>();
    myclass.Test();
}
ContainerBuilder=newcontainerbuilder();
builder.RegisterType().As();
builder.Register(c=>
{
ProxyGenerator g=新的ProxyGenerator();
objectproxy=g.CreateClassProxy(typeof(MyClass),new MyLogInterceptor());
ICanLog proxyICanLog=(ICanLog)代理;
proxyICanLog.Log=c.Resolve();
返回代理;
}).As();
使用(var container=builder.Build())
{
objectContext.Container=容器;
IMyClass myclass=container.Resolve();
myclass.Test();
}
但结果没有输出“开始”/“结束”,为什么

如果我创建AutoLogModule,尝试自动构建日志属性实例

    public class AutoLogModule : Autofac.Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        var type = registration.Activator.LimitType;
        if (HasPropertyDependencyOnClass(type))
        {
            registration.Activated += InjectClassViaProperty;
        }
    }

    private bool HasPropertyDependencyOnClass(Type type)
    {
        return type.GetProperties().Any(property => property.CanWrite && property.PropertyType==typeof(ILog));
    }

    private void InjectClassViaProperty(object sender, ActivatedEventArgs<object> evt)
    {
        var type = evt.Instance.GetType();
        var propertyInfo = type.GetProperties().First(x => x.CanWrite && x.PropertyType==typeof(ILog));

        ILog log = new MyLog();
        propertyInfo.SetValue(evt.Instance, log, null);
    }
}
公共类AutoLogModule:Autofac.Module
{
受保护的覆盖无效AttachToComponentRegistration(IComponentRegistry ComponentRegistration,IComponentRegistration注册)
{
变量类型=registration.Activator.LimitType;
if(HasPropertyDependencyOnClass(类型))
{
注册。已激活+=属性;
}
}
私有布尔HasPropertyDependencyOnClass(类型)
{
返回type.GetProperties().Any(property=>property.CanWrite&&property.PropertyType==typeof(ILog));
}
私有void InjectClassViaProperty(对象发送方,ActivatedEventArgs evt)
{
var type=evt.Instance.GetType();
var propertyInfo=type.GetProperties().First(x=>x.CanWrite&&x.PropertyType==typeof(ILog));
ILog log=new MyLog();
propertyInfo.SetValue(evt.Instance,log,null);
}
}
以下是测试代码:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<MyLog>().As<ILog>();
builder.Register(c =>
{
    ProxyGenerator g = new ProxyGenerator();
    object proxy = g.CreateClassProxy(typeof(MyClass), new MyLogInterceptor());
    ICanLog proxyICanLog = (ICanLog)proxy;
    proxyICanLog.Log = c.Resolve<ILog>();
    return proxy;
}).As<IMyClass>();

using (var container = builder.Build())
{
    objectContext.Container = container;
    IMyClass myclass = container.Resolve<IMyClass>();
    myclass.Test();
}
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<MyLog>().As<ILog>();
builder.RegisterModule(new AutoLogModule());
builder.Register(c =>
{
    ProxyGenerator g = new ProxyGenerator();
    object proxy = g.CreateClassProxy(typeof(MyClass), new MyLogInterceptor());
    //ICanLog proxyICanLog = (ICanLog)proxy;
    //proxyICanLog.Log = c.Resolve<ILog>();
    return proxy;
}).As<IMyClass>();

using (var container = builder.Build())
{
    objectContext.Container = container;
    IMyClass myclass = container.Resolve<IMyClass>();
    myclass.Test();
}
ContainerBuilder=newcontainerbuilder();
builder.RegisterType().As();
RegisterModule(新的AutoLogModule());
builder.Register(c=>
{
ProxyGenerator g=新的ProxyGenerator();
objectproxy=g.CreateClassProxy(typeof(MyClass),new MyLogInterceptor());
//ICanLog proxyICanLog=(ICanLog)代理;
//proxyICanLog.Log=c.Resolve();
返回代理;
}).As();
使用(var container=builder.Build())
{
objectContext.Container=容器;
IMyClass myclass=container.Resolve();
myclass.Test();
}
结果是测试方法抛出 “对象引用未设置为对象的实例。” 在Log.Write中(“测试”)


如何编写此功能?

我知道这是一篇相当古老的文章,但当我试图用
Autofac
完成同样的事情时,我发现了帮助我实现它的方法。我会回答,以防万一这对别人有帮助

在我的例子中,我正在使用Autofac 4.92和名为Autofac.Extras.DynamicProxy 4.5.0的
DynamicProxy
附加包作为文档

我发现您在注册
拦截器时存在差异。即使你正在做的是我最初会做的;不是Autofac文档当前所说的关于如何:


我希望这个答案会有所帮助。无论如何,Autofac文档一步一步地解释了如何做到这一点,以防我的代码可能会错误地跳过某些相关部分。

我知道这是一篇相当古老的文章,但当我试图用
Autofac
完成同样的事情时,我发现了帮助我实现它的方法。我会回答,以防万一这对别人有帮助

在我的例子中,我正在使用Autofac 4.92和名为Autofac.Extras.DynamicProxy 4.5.0的
DynamicProxy
附加包作为文档

我发现您在注册
拦截器时存在差异。即使你正在做的是我最初会做的;不是Autofac文档当前所说的关于如何:

我希望这个答案会有所帮助。无论如何,Autofac文档一步一步地解释了如何做,以防我的代码可能会错误地跳过某些相关部分