samedi 25 avril 2015

How to use single object and fill its properties throughout all sub process in single webapi request?

I have an Asp.net WebApi Project and i am using Simple Injector for dependency injection.

I have some messages, message handlers , decorators on my project. I am using decorator pattern.

I need to keep details of each process and i need to save them to database.For example, i want to keep details like : when request started, what happened on sub process and when process finished, what was the request body , what was the response body etc. First i need to write details to an object, and then i will save this object to database.

Imagine that this process detail keeper class name is ProcessDetail. So it has some properties RequestBody, ResponseBody, StartTime, EndTime etc...

How to keep same ProcessDetail object, for each steps of the decorator pattern and fill it for each process ?

My code sample here :

CommandHandler

public interface ICommandHandler<in TCommand, out TResult>
    where TCommand : ICommand<TResult>
{
    TResult Handle(TCommand command);
}

CommandProcessor

public interface ICommandProcessor
{
    object Process(object command);
    TResult Process<TResult>(ICommand<TResult> command);
}

Command

public interface ICommand<TResult>
{
}

TracingDecorator

public class TracingCommandHandlerDecorator<TCommand, TResult>
    : ICommandHandler<TCommand, TResult>
    where TCommand : ICommand<TResult>
{
    private readonly ICommandHandler<TCommand, TResult> _innerHandler;

    public TracingCommandHandlerDecorator(
        ICommandHandler<TCommand, TResult> innerHandler)
    {
        _innerHandler = innerHandler;
    }

    public TResult Handle(TCommand command)
    {
        try
        {
            Debug.Write(command);
            var result = _innerHandler.Handle(command);
            Debug.Write(result);
            return result;
        }
        catch (Exception ex)
        {
            Debug.Write(ex);
            throw ex;
        }
    }
}

Validating Decorator

public class ValidatingCommandHandlerDecorator<TCommand, TResult>
    : ICommandHandler<TCommand, TResult>
    where TCommand : ICommand<TResult>
{
    private readonly ICommandHandler<TCommand, TResult> _innerHandler;


    public ValidatingCommandHandlerDecorator(
        ICommandHandler<TCommand, TResult> innerHandler)
    {
        _innerHandler = innerHandler;
    }

    public TResult Handle(TCommand command)
    {
        var context = new ValidationContext(command, null);
        Validator.ValidateObject(command, context);
        return _innerHandler.Handle(command);
    }
}

TransactionalCommand Decorator

public class TransactionalCommandHandlerDecorator<TCommand, TResult>
    : ICommandHandler<TCommand, TResult>
    where TCommand : ICommand<TResult>
{
    private readonly ICommandHandler<TCommand, TResult> _innerHandler;
    private readonly OneDeskDbContext _dbContext;

public TransactionalCommandHandlerDecorator(
    ICommandHandler<TCommand, TResult> innerHandler, 
    OneDeskDbContext dbContext)
    {
        _innerHandler = innerHandler;
        _dbContext = dbContext;
    }

    public TResult Handle(TCommand command)
    {
        try
        {
            var result = _innerHandler.Handle(command);
            _dbContext.Commit();
            return result;
        }
        catch (Exception ex)
        {
            _dbContext.Rolback();
            throw ex;
        }
    }
}

Global.asax

Container = new Container();
Container.RegisterSingle<ICommandProcessor, IocCommandProcessor>();
Container.RegisterManyForOpenGeneric(typeof(ICommandHandler<,>),
    Assembly.GetExecutingAssembly());
Container.RegisterDecorator(typeof(ICommandHandler<,>),
    typeof(TransactionalCommandHandlerDecorator<,>));
Container.RegisterDecorator(typeof(ICommandHandler<,>),
    typeof(TracingCommandHandlerDecorator<,>));
Container.RegisterDecorator(typeof(ICommandHandler<,>),
    typeof(ValidatingCommandHandlerDecorator<,>));

Container.RegisterSingle<ISmsService, DummpySmsService>();
Container.RegisterWebApiRequest<OneDeskDbContext, OneDeskDbContext>();

Container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
Container.Verify();
GlobalConfiguration.Configuration.DependencyResolver = 
    new SimpleInjectorWebApiDependencyResolver(Container);

Aucun commentaire:

Enregistrer un commentaire