1

I have a couple of method attributes which do some logging. Our logging code sits behind an interface (ILog) and I'd like it if the attributes were only dependent upon that interface as opposed to an implementation. This isn't really about testability or dependency inversion so much as it is about keeping the coupling of components clean.

An example would be where we have a web (Mvc) specific attribute as follows:

HandleExceptionAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        LogFactory.CreateInstance().Info("message here", "log entry type");
    }
}

LogFactory is dependant upon the concrete implementation Log.cs. This has the unfortunate effect of coupling my Web DLL to the DLL containing the concrete implementation - making the overall system more rigid and fragile.

Any other location where such a dependency becomes apparent we just use our IOC container to inject it. This is exactly what I'd like to do now with the attribute but I'm not really sure how to!

So, my question is: How can a concrete dependency be injected into a .NET Framework attribute behind an interface (preferably via an IOC container like StructureMap - but anything that works will be fine)?

Zac Seth
  • 2,742
  • 5
  • 37
  • 56

2 Answers2

4

See this article - How to use Ninject to inject dependencies into ASP.NET MVC ActionFilters

http://codeclimber.net.nz/archive/2009/02/10/how-to-use-ninject-to-inject-dependencies-into-asp.net-mvc.aspx

viliks
  • 349
  • 3
  • 5
  • That's real nice - I don't use Ninject (StructureMap is my IOC of choice) but the same principle should apply perfectly with any of the major containers - overriding the ActionInvoker is something I need to learn more about... Cheers, – Zac Seth Jul 05 '10 at 07:49
1

Could you not make the logger an interface and pass it to either a property in the Attribute or through the constructor:

LoggerAttribute
{
    [Dependency]
    public ILogger Logger {get; set;}

    ...
}

If it were me though I would go for putting the logger in a base class and set up a property on it.

Burt
  • 7,680
  • 18
  • 71
  • 127
  • This is probably the route I'm going to end up taking - I just need to figure out injection using Attributes and StrucuteMap... – Zac Seth Oct 21 '09 at 22:53
  • I ran into the same problem, I chose to use a properties instead of constructor arguments because attributes only support constant values when applied to types. So I don't think the use of constructor arguments is an option, when used on attributes (unless you are injecting constant values). – Paul Fryer Feb 21 '12 at 20:35