AOP suggestion without IOC

孤人 提交于 2020-02-15 06:34:59

问题


I need to introduce AOP in an existing WCF service, basically for exception wrapping and logging. I need an AOP framework in .NET 4 (not 4.5), without need to do IOC injection because it will be too costly to introduce in existing code. In my research I found the following:

  • PostSharp: very nice and straightforward but paid, I need a free one
  • NConcern: latest version is build for .NET 4.5, previous versions is buggy with my code. Also it works with CNetpune which modify the assembly, not exactly what I want.
  • Spring.NET: didn't find a way to do AOP with IOC
  • others are too old and not maintained any more.

any suggestion ?


回答1:


You can implement your AOP with using WCF Interceptors like this:

First create your BaseServiceInspector. Implement IDispatchMessageInspector and IParameterInspector

Use methods AfterReceiveRequest to initialize you request properties, BeforeCall to log before service is calling and AfterCall to log Service is Called.

My implementation like this:

/// <summary>
/// This class responsible to inspect service request and response
/// Service operations is also logged within this class
/// </summary>
internal class BaseServiceInspector : IClientMessageInspector, IDispatchMessageInspector, IParameterInspector
{
    private Guid requestIdentifier;
    private DateTime requestDate;
    private string serviceResult = String.Empty;
    private string consumerIPAddress = String.Empty;
    private string operationName = String.Empty;


    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        try
        {
            requestIdentifier = Guid.NewGuid();
            requestDate = DateTime.Now;
            operationName = ServiceHelper.GetServiceOperationName(OperationContext.Current);
            consumerIPAddress = ServiceHelper.GetServiceConsumerIPAddress(OperationContext.Current);

            return null;
        }
        catch
        {
            throw;
        }
    }

    public object BeforeCall(string operationName, object[] inputs)
    {
        try
        {
            ServiceHelper.LogServiceIsCalled(operationName, requestIdentifier, consumerIPAddress, JsonConvert.SerializeObject(inputs, Formatting.Indented));
        }
        catch
        {
            //Dont break the flow for log exception
        }

        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        TimeSpan executeDuration = DateTime.Now - requestDate;
        ServiceHelper.LogServiceIsExecuted(operationName, executeDuration.Milliseconds,requestIdentifier, consumerIPAddress, serviceResult);
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;

    }
}

Then create your Aspect

/// <summary>
/// Customized service behavior for service types. If services are designed as WCF service
/// All services should have this attribute
/// </summary>
public class BaseServiceBehavior : Attribute, IServiceBehavior
{

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        BaseServiceInspector baseServiceInspector = new BaseServiceInspector();
        foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
        {
            foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
            {
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(baseServiceInspector);

                foreach (var operation in endpointDispatcher.DispatchRuntime.Operations)
                {
                    operation.ParameterInspectors.Add(baseServiceInspector);
                }
            }
        }
    }
}

Finally add your Aspect to Service:

[BaseServiceBehavior]
public class MathService : IMathService
{
    //...
}

Hope it works for you.

More info for Interceptors

You can check my github repo as well for detail implementation:

Service-Framework/



来源:https://stackoverflow.com/questions/44033715/aop-suggestion-without-ioc

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!