Structure map Generic type scanner

High level

With StructureMap, can I define an assembly validation rule that for the interface IRequestService<T>

will return an object named TRequestService

Examples:

  • FooRequestService

    entered when IRequestService<FooRequest>

    requested
  • BarRequestService

    entered upon request IRequestService<BarRequest>

More details

I have a generic interface defined

public interface IRequestService<T> where T : Request
{
    Response TransformRequest(T request, User current);
}

      

and then I have several Request objects that implement this interface

public class FooRequestService : IRequestService<Foo>
{
    public Response TransformRequest(Foo request, User current) { ... }
}

public class BarRequestService : IRequestService<Bar>
{
    public Response TransformRequest(Bar request, User current) { ... }
}

      

Now I am at the point where I need to register these classes so that the StructureMap knows how to create them because in my controller I want to have the following ctor (which I want the StructureMap to embed FooRequestService

in)

public MyController(IRequestService<Foo> fooRequestService) { ... }

      

Right now, to work around my problem, I have implemented an empty interface and instead of FooRequestService

implementing a generic interface, I am implementing this empty interface

public interface IFooRequestService : IRequestService<Foo> { }

      

Then my ctor controllers look like this works with a standard StructureMaps scanner

public MyController(IFooRequestService fooRequestService) { ... }

      

How do I create a rule with a StructureMap build collector to register all objects named TRequestService with IRequestService<T>

(where T = "Foo", "Bar", etc.) so that I don't have to create these empty interface definitions

To throw something else into the mix where I'm working with the assembly handling StructureMap, there is no reference to the assembly that defines IRequestService<T>

, so some kind of reflection has to be used when doing this. I looked at the answer to " Loading StructureMap for Generic Types with Scan ", but it seems that this answer requires a reference to the assembly that contains the interface definition.

I'm on my way to creating a custom StructureMap.Graph.ITypeScanner, but I'm kind of stuck on what to do there (mostly because I have little experience with reflection).

+2


source to share


1 answer


You are on the right track with a scanner. Fortunately, there is one built in to StructureMap. Unfortunately, this has not yet been released. Get the latest data from the torso and you will see several new things available in the scanner configuration. Below is an example of your needs.

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        Scan(x =>
        {
            x.TheCallingAssembly();
            //x.AssembliesFromApplicationBaseDirectory();
            x.WithDefaultConventions();
            x.ConnectImplementationsToTypesClosing(typeof (IRequestService<>));
        });
    }
}

      

First you need to tell your scanner configuration which assemblies should be included in the scan. The commented out AssembliesFromApplicationBaseDirectory () method can also help if you are not running the registry per assembly.

To use your generic types in a container, use ConnectImplementationsToTypesClosing .



For an example on how to configure the use of registries when configuring a container see http://structuremap.sourceforge.net/ConfiguringStructureMap.htm

If you like, you can skip using registries altogether and just scan into ObjectFactory.Initialize .

Hope it helps.

+2


source







All Articles