I've created custom action filter attribute for logging error and save logs into database:
public class LogAttribute : ActionFilterAttribute
{
public string Description { get; set; }
public IUnitOfWork Uow { get; set; }
public ILogActionService LogActionService { get; set; }
public IApplicationUserManager ApplicationUserManager { get; set; }
public LogAttribute(string desciption)
{
Description = desciption;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//var userId = filterContext.HttpContext.User.Identity.GetUserId();
//var user = await ApplicationUserManager.FindByIdAsync(2);
var model = new LogAction(filterContext.ActionDescriptor.ActionName,
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, Description);
LogActionService.AddLog(model);
Uow.SaveAllChanges();
base.OnActionExecuted(filterContext);
}
}
So, I also created custom filter provider for injecting my dependency using StructureMap:
public class StructureMapFilterProvider : FilterAttributeFilterProvider
{
private Func<IContainer> _container;
public StructureMapFilterProvider(Func<IContainer> container)
{
_container = container;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
var container = _container();
foreach (var filter in filters)
{
container.BuildUp(filter.Instance);
yield return filter;
}
}
}
Then I've registered that in Global.asax:
cfg.For<IFilterProvider>().Use(new StructureMapFilterProvider(() => SmObjectFactory.Container));
cfg.Policies.SetAllProperties(x => x.Matching(p => p.DeclaringType.CanBeCastTo(typeof(ActionFilterAttribute)) &&
p.DeclaringType.Namespace.StartsWith("MyNamespace") &&
!p.PropertyType.IsPrimitive &&
p.PropertyType != typeof(string)));
Everything should be ok, But when I decorate my action method with Log attribute, I get Object reference not set to an instance of an object. I set break point in OnActionExecuted it tells that LogActionService is null:
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//var userId = filterContext.HttpContext.User.Identity.GetUserId();
//var user = await ApplicationUserManager.FindByIdAsync(2);
var model = new LogAction(filterContext.ActionDescriptor.ActionName,
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, Description);
LogActionService.AddLog(model);
Uow.SaveAllChanges();
base.OnActionExecuted(filterContext);
}