1
votes

I've been searching all day and can't figure this out. I hope it hasn't been asked before.

ObjectFactory.Initialize(
    x =>
        {
            x.For(typeof (IRepository<>))
             .Use(typeof(Repository<>))
             .CtorDependency<DbContext>("dbContext")
             .Is(new DbContext());
        }
    );

I need structuremap to use a new instance of 'DbContext' each time it creates a new instance of 'Repository'. Right now I believe it is reusing 'DbContext' and its causing issues. I believe it is reusing only 'DbContext' because I have tried setting the lifecycle on 'Repository' to PerRequest with the same result. Any help is greatly appreciated.

I'm new to StructureMap and Dependency Injection so I may be incorrect in my analysis.

Update

@PHeiberg thank you so much for your answer. It rang a bell I remember seeing that lambda expression starting with '()' that I hadn't seen before. I was super excited that this was it. I tried your code verbatim and it can't resolve Ctor so I changed it to this.

                        x.For(typeof(IRepository<>))
                      .HttpContextScoped()
                      .Use(typeof(Repository<>))
                      .CtorDependency<DbContext>("dbContext")
                      .Is(() => new DbContext());       

And I receive the following compilation error

"Cannot resolve method 'Is(Lamda exression)', candidates are: StructureMap.Pipeline.ConfiguredInstance Is(object) (in class ChildInstanceExpression) StructureMap.Pipeline.ConfiguredInstance Is(StructureMap.Pipeline.Instance) (in class ChildInstanceExpression).

I have seen this message before I remember and it resulted in my trying to register my dbContext Type although I dont know if you can nor if I was doing correctly, say x.For(concrete type).Use(concrete type).

2
I don't know StructureMap at all, but looking at your code, I'd guess it is always using the DbContext instance you created when registering Repository (or when the delegate gets invoked - probably once for your app). If you want your container to control the lifecycle of DbContext you'll probably have to register it separately.Merlyn Morgan-Graham

2 Answers

0
votes

Your analysis is correct. You're configuring structuremap to use the instance you're passing in to the Is method, effectively creating a singleton. In order to create a new instance per Http request, use:

x.For(typeof (IRepository<>))
  .HttpContextScoped()
  .Use(typeof(Repository<>))
  .Ctor<DbContext>("dbContext")
  .Is(() => new DbContext());

Notice the lambda that is the Is argument. It causes the evaluation of the creation to be done each time the dependency is resolved. The HttpContextScoped method cause Structure Map to cache the Repository during the Http Request.

0
votes

Use

x.For<IRepository>()
    .HttpContextScoped()
    .Use<Repository>()
    .CtorDependency<DbContext>("dbContext")
    .Is(ctx => new DbContext());

.Is() accepts a type of Func<IContext, T>