StructureMap 3 get request type

I have the following StructureMap registrations working in 2.6.4 and I am finally upgrading to the latest SM (3.1.2 at the time of this writing). And you need to update it as IContext.BuildStack no longer exists.

Here is the old working version since 2.6.4:

        initialization.For(typeof(IRepository<,>))
                             .Use(context =>
                             {
                                 var genericArgs = context.BuildStack.Current.RequestedType.GetGenericArguments();

                                 return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1], repositoryName);
                             }
            );

      

So what I figured out was to change it to this:

        initialization.For(typeof (IRepository<,>))
            .Use("IRepository<,>", context =>
                                   {
                                       var genericArgs = context.ParentType.GetGenericArguments();

                                       return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1],
                                           repositoryName);
                                   }
            );

      

But context.ParentType is null. When I look at the context.RootType it is set to System.Object, which is clearly not what I want.

My test code for getting an instance of this repository:

var userRepository = ObjectFactory.GetInstance<IRepository<User, Guid>>();

      

I don't see any other property that has this information, but I'm guessing I'm missing something.

+3


source to share


2 answers


You haven't missed anything. Someone posted a mock question on GitHub: https://github.com/structuremap/structuremap/issues/288 . Jeremy Miller, author of structure structure, replied:

This will be a new development. This should be in version 3.2.

The suggested solution is to create a custom instance and override the ClosingType method. You can do it like this:



public class CustomInstance : Instance
{
    public override IDependencySource ToDependencySource(Type pluginType)
    {
        throw new NotImplementedException();
    }

    public override Instance CloseType(Type[] types)
    {
        var repository = RepositoryFactory.GetInstance(types[0], types[1], repositoryName);                                                           
        return new ObjectInstance(repository);
    }

    public override string Description
    {
        get { throw new NotImplementedException(); }
    }

    public override Type ReturnedType
    {
        get { return typeof (IRepository<,>); }
    }
}

      

Now you need to wire the open generic type to the closing type, for example:

initialization.For(typeof (IRepository<,>)).Use(new CustomInstance());

      

+6


source


I've added a new example to the StructureMap 3 codebase for this scenario based on your question:

https://github.com/structuremap/structuremap/blob/master/src/StructureMap.Testing/Acceptance/builder_for_open_generic_type.cs



I have to ask what is the purpose of something like RepositoryBuilder

if you are using an IoC container?

In any case, this implementation should be more efficient than the old reflection-based approach.

+4


source







All Articles