0
votes

I am new to StructureMap and have the following issue which seems to be the reverse of issues other people are having. I have a generic UnitOfWorkClass defined as follows:

public class UnitOfWork<TContext> : IUnitOfWork
    where TContext : IContext, new()
{
    ....
}

However I'm baffled about how you'd register this to resolve if I've got several different possibilities for the concrete instance.

I've seen plenty of examples where people have a generic interface such as:

StructureMap Auto registration for generic types using Scan

So I guess the question could be asked if I need to re-look at my design too!

Thanks a lot!

# EDIT POSSIBLE SOLUTION?

So I have a class which takes two parameters into the constructor:

public MyClass(IUnitOfWork firstConstructor, 
    IUnitOfWork secondConstructor)
{
    ...
}

Then as my object graph gets built I do the following:

ObjectFactory.Initialize(cfg =>
{
    var firstContext = cfg.For<IContext>().Use<MyFirstContext>();
    var secondContext = cfg.For<IContext>().Use<MySecondContext>();

    var firstUnitOfWork =
        cfg.For<IUnitOfWork>().Use<UnitOfWork<MyFirstContext>>()
        .Ctor<IContext>().Is(firstContext);

    var secondUnitOfWork =
        cfg.For<IUnitOfWork>().Use<UnitOfWork<MySecondContext>>()
        .Ctor<IContext>().Is(secondContext);

    cfg.For<IMyClass>().Use<MySecondContext>()
        .Ctor<IUnitOfWork>("firstConstructor").Is(firstUnitOfWork)
        .Ctor<IUnitOfWork>("secondConstructor").Is(secondUnitOfWork);
});

So what I've done here is:

  • Resolved my dependency for IContext and stored them in variables
  • Injected the resolved IContext into my IUnitOfWork constructor
  • I can then resolve the correct generic UnitOfWork constructor correctly

It doesn't feel perfect but I think this suits my needs...

1
If the interface is not generic, how could StructureMap ever find out what type to 'fill in' in the TContext type parameter? Either you must supply that type by registering a closed version of it explicitly, or you make the interface generic. The choice is up to you.Steven
That is a good point, however in this particular example it would make the code less clean just to push round a type to an interface when I just need it for resolving the class, I think I've found a solution which I'll edit in my question above to see if you think it makes sense!Steve Newstead
The problems you have are caused by ambiguity in your design. You should remove that ambiguity. For instance, create multiple specific unit of work interfaces, such as: IFirstUnitOfWork, ISecondUnitOfWork.Steven

1 Answers

2
votes

I'm not entirely sure I understand what you want, but if you made the interface generic as in IUnitOfWork then you can register like this:

ObjectFactory.Initialize(x =>
{
    x.For(typeof(IUnitOfWork<>)).Use(typeof(UnitOfWork<>));
}

and StructureMap will supply the implementing class with the correct type. Does that give you waht you need?