3

I'm pretty much wanting to do what this guy describes (passing a dependency into a custom attribute):

How to use dependency injection with an attribute?

however, I want to do it with StructureMap 4.0, not Ninject.

My project is set up with the custom attribute in my Data Layer dll, and I already have StructureMap installed and working with my controllers in my UI Layer.

I have determined I probably have to do Setter injection with StructureMap:

http://docs.structuremap.net/ConstructorAndSetterInjection.htm

however, it is not working correctly for me with my custom attribute in the data layer.

I figured that in order to make things work that I should install Structuremap into my data layer as well, and put this in IoC.cs:

        public static IContainer Initialize()
    {
        Container container = new Container(x =>
        {

            x.ForConcreteType<My_AuthorizeADAttribute>().Configure.Setter<My_AppDataContext>().IsTheDefault();  //not sure about this line
        });

        return container;
    }

oh.. my custom Attribute:

public class My_AuthorizeADAttribute : AuthorizeAttribute
{
    public IMy_Data_Context _dataContext;

    [SetterProperty] 
    public IMy_Data_Context DataContext
    {
        get { return _dataContext; }
        set { _dataContext = value;  }
    }

Is this the right thing to do? I'm thinking I left out a step. (but then again, I haven't really set up Structuremap on multiple dlls in the same project. Wondering if multiple projects with StructureMap needs something more.

At present, the app will run, but the Property in the Custom Attribute won't populate.

Update: This StackOverflow question has been helpful:

How do I get StructureMap working with an AngularJs / MVC5 and WebApi2 web project

Community
  • 1
  • 1
Kevin
  • 99
  • 1
  • 12

3 Answers3

0

It is indeed the line you are unsure of.

x.ForConcreteType<My_AuthorizeADAttribute>().Configure.Setter<My_AppDataContext>().IsTheDefault();  //not sure about this line

This should instead specify what you actually want to inject into the setter on instantiation, like so:

x.ForConcreteType<My_AuthorizeADAttribute>().Configure.SetterDependency<IMy_Data_Context>().Is(new My_AppDataContext());

This will inject your concrete implementation of IMy_Data_Context, My_AppDataContext, into the type My_AuthorizeADAttribute. If you had multiple properties of the IMy_Data_Context type on your attribute you may need to worry about how to assign multiple defaults using the default syntax you were working off of, but that doesn't appear to be your use case.

Jonathon Chase
  • 9,396
  • 21
  • 39
  • hmmm.. .SetterDependency isn't coming up. (it is not an option). is there a reference I need for that? – Kevin Mar 01 '16 at 20:43
  • ok, I'm assuming that changing .SetterDependency to .Setter is the proper terminology, as a review of the 4.0 code does not show .SetterDependency anywhere. also their new docs are here: http://structuremap.github.io/setter-injection/ unfortunately it is still not working. Is having an IoC.cs file in each dll the proper way to set up multiple projects? – Kevin Mar 01 '16 at 22:48
0

I responded to you in the StructureMap Gitter room, but I'll do it here too. Are you calling Container.BuildUp(object) against your attribute object after it's created? StructureMap isn't building the attribute objects at runtime, it can only apply setters afterward. See the bottom section of this: http://structuremap.github.io/setter-injection/ for more information on BuildUp().

0

ok, after much research, apparently this is the best option for me now. it means the Attribute has a dependency on StructureMap, but then again, [SetterProperty] would have it as well.

Asp.Net MVC Custom Validation Attribute With StructureMap

Community
  • 1
  • 1
Kevin
  • 99
  • 1
  • 12