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?