Log method parameters and return type using Enterprise library logging application block

664 views Asked by At

Is there any way to log method parameter name , its value and return type value using Enterprise library logging application block. I have provided a code sample below. The requirement is to log it's methods input parameters value and its return type value

// Complex Types
public class UserDetails
{
    public string UserName { get; set; }
    public int UserAge { get; set; }
    public string UserAddress { get; set; }
}
public class User
{
    public string UserId { get; set; }
    public string Pwd { get; set; }
}

//Interface
public interface IService
{
    UserDetails GetUserDetails(User ReqUser);
}

//Imp
public class Service : IService
    {

        [LogCallHandler(Categories = new string[] { "General" }, LogBeforeCall = true, LogAfterCall = true ,
         BeforeMessage = "This occurs before the call to the target object",AfterMessage="This occured after method call",IncludeParameters=true)]
        public UserDetails GetUserDetails(User ReqUser)
        {
            UserDetails oUD = new UserDetails();
            oUD.UserName = "hhh" + ReqUser.UserId;
            oUD.UserAge = 100;
            oUD.UserAddress = "HHHHHHHHHHHHHHHHHHHHHHH";
            return oUD;
        }

        #endregion
    }

//Usage
private void button2_Click(object sender, EventArgs e)
{
    IUnityContainer container = new UnityContainer().LoadConfiguration();
    container.AddNewExtension<EnterpriseLibraryCoreExtension>();
    IService service = container.Resolve<IService>();
    User nUser = new User();
    nUser.UserId = "TTTTT";
    nUser.Pwd = "XXXXX";
    UserDetails mm = service.GetUserDetails(nUser);

}

Could anyone please explain how to implement this using Enterprise library logging application block?

2

There are 2 answers

0
Hasan On

You can use EntLib LogCallHandler by code:

container.AddNewExtension<EnterpriseLibraryCoreExtension>();
container.RegisterType<IService, Service>(
    new InterceptionBehavior<PolicyInjectionBehavior>(),
    new Interceptor<TransparentProxyInterceptor>());

Or by config file:

<unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    <namespace name="LoggingCallHandler" />
    <assembly  name="LoggingCallHandler" />
    <container>
        <extension type="Interception" />
        <extension type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity.EnterpriseLibraryCoreExtension, Microsoft.Practices.EnterpriseLibrary.Common" />
        <register type="IService" mapTo="Service">
            <interceptor type="TransparentProxyInterceptor" />
            <policyInjection />
        </register>
    </container>
</unity>

Here, LoggingCallHandler is namespace/assembly for your service class. Alternatively, you can define your type alias like this:

<alias alias="Service" type="LoggingCallHandler.Service, LoggingCallHandler"/>
<alias alias="IService" type="LoggingCallHandler.IService, LoggingCallHandler"/>

See this or this discussion for full configuration including logging block configuration.

2
Hasan On

You can write an OnMethodBoundaryAspect to intercept your method calls using PostSharp API.
OnMethodBoundaryAspect.OnEntry method includes MethodExecutionArgs parameter which provides all the information you need about the method and its arguments.

See this post for a sample logging aspect implementation very close to your requirements.

// This method is executed before the execution of target methods of this aspect. 
public override void OnEntry( MethodExecutionArgs args )
{
    // Build method information to log.
    string methodInfo = BuildMethodInformation(args.Arguments);

    // continue with your logging...
}

You can get method parameters via Arguments member of MethodExecutionArgs parameter like this:

private string BuildMethodInformation(Arguments arguments)
{
    var sb = new StringBuilder();
    sb.Append(_methodName);
    foreach (var argument in arguments.ToArray())
    {
        sb.Append(arguments.GetArgument( i ) ?? "null");
    }
    return sb.ToString();
}

For method parameters, check this or this samples. They are built for caching but BuildCacheKey/GetCacheKey methods include all the information you need to get argument information of a method.