4

所以,我有这个问题,似乎没有人能够提供帮助。因此,与其继续抨击,我将把它扔出去,寻找其他方法来剥皮这只特殊的猫。

我目前有以下内容:

public interface ICustomerService
{
    Customer GetCustomer(int id);
}

public class CustomerService : ICustomerService
{
    public Customer GetCustomer(int id)
    {
        ...
    }
}

...并且使用 Unity,我有 IOC 设置,同时配置拦截,如:

IUnityContainer ioc = new UnityContainer();
ioc.RegisterType<ICustomerService, CustomerService>()
    .Configure<Interception>()
    .SetInterceptorFor<ICustomerService>(new InterfaceInterceptor());

我想要实现的是能够像这样在界面中放置属性:

public interface ICustomerService
{
    [Log]
    Customer GetCustomer(int id);
}

...定义为:

public class LogAttribute: HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogHandler();
    }
}  

...然后在 LogHandler 类中执行我想要的所有日志记录:

public class LogHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        ... log stuff
    }
}

我想要实现的是一个跟踪/记录系统,其中处理程序记录正在调用的 namespace.class.methodname,以及调用它的父 namespace.class.methodname。我尝试使用“输入”IMethodInvocation 参数来获取我想要的信息但没有成功,问题是,输入返回“ICustomerService”接口,同时检查父级的堆栈帧返回父级的实现类(例如.CustomerService)意味着当我尝试使用 namespace.class.methodname 作为实体 ID 创建树结构时,ID 和 parentID 不匹配。

将参数放入 [Log] 属性也不会真正起作用,因为我可以在那里放什么?如果我输入接口名称,我仍然有与上面相同的问题,其中一个的 ID 是一个接口,而父级是实现类。而且,我不能将实现类名放在接口的属性中,因为这首先违背了拥有接口的目的!

所以,这就是两难境地。有人有新的想法吗?

4

2 回答 2

1

我已经使用 Unity 和 Interception 进行日志记录。由于我极度缺乏配置设置技能,我不得不以编程方式进行。您需要设置至少一个拦截器,以及一个或多个策略对象。哦,是的,这UnityContainer.Configure<Interception>很关键。

有点像这样:

// I'm using the TransparentProxyInterceptor because I want to trace EVERYTHING...
var intp = myUnityContainer.Configure<Interception>().
    SetInterceptorFor(typeof(MyTypeToLog), new TransparentProxyInterceptor());

var policy = intp.AddPolicy("somePolicyName");

policy.AddMatchingRule<TypeMatchingRule>(
    new InjectionConstructor(
        new InjectionParameter(typeof(MyTypeToLog)))
          .AddCallHandler(typeof(MyCallHandler), 
               new ContainerControlledLifetimeManager());

当然我还需要定义拦截调用处理程序:

public class MyCallHandler : ICallHandler, IDisposable
{
    public IMethodReturn Invoke(IMethodInvocation input, 
        GetNextHandlerDelegate getNext)
    {
        var methodReturn = getNext().Invoke(input, getNext);

        // log everything...
        LogMethodCall(input, methodReturn);

        // log exception if there is one...
        if (methodReturn.Exception != null)
        {
            LogException(methodReturn);
        }

        return methodReturn;
    }
}
于 2010-10-08T18:10:13.660 回答
1

我最终使用 PostSharp 来实现完全像这样的日志记录。http://www.postsharp.org

于 2009-12-01T15:04:50.943 回答