0

Suppose I have the following hierarchy which I wish to instantiate with DI:

DatabaseService(IDatabaseRepository) : IDatabaseService
Database1Service(IDatabaseRepository) : IDatabase1Service
Database2Service(IDatabaseRepository) : IDatabase2Service
DatabaseRepository(IUnitOfWork)  : IDatabaseRepository
DatabaseRepository2(IUnitOfWork) : IDatabaseRepository
UnitOfWork(string) : IUnitOfWork

Is there a method in Stucturemap that would let me do this?

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        //default-convention-scan code here

        //this is the unit of work for almost all of my interface implementations
        //i.e. new DatabaseService(new DatabaseRepository(new IUnitOfWork("Database1")))
        //    new Database1Service(new DatabaseRepository(new IUnitOfWork("Database1")))
         For<IUnitOfWork>()
             .Use(new UnitOfWork("Database1"));

         //Database2Service needs a separate implementation Of UnitOfWork
        //i.e. new Database2Service(new DatabaseRepository(new IUnitOfWork("Database2")))
         For<IUnitOfWork>().IfDescendantDependencyOf<IDatabase2Service>()
             .Use(new UnitOfWork("Database2"))
    }
}

If it's not clear, I want all injected IUnitOfWorks to point to the singleton new UnitOfWork("Database1"), except if it was injected while trying to construct an instance of IDatabase2Service, where it should use the singleton new UnitOfWork("Database2").

Arithmomaniac
  • 4,604
  • 3
  • 38
  • 58
  • Do both databases share the exact same database schema? – Steven Mar 18 '15 at 22:08
  • In that case you are violating the Liskov Substitution Principle. You should create a different interface for the second database. – Steven Mar 18 '15 at 22:20
  • 1
    @Steven, I don't suppose you could be so kind as to expand on how this would violate the LSP? Surely if it's only the storage mechanism that is changing and it has the exact same schema then the client is still talking to the same interface and implementation? – Joseph Woodward Mar 19 '15 at 13:27
  • @JoeMighty: The LSP says that you should be able to swap implementations of the same abstraction without the consumer to know the difference. The OP uses the same `IDatabase` abstraction over multiple database schemas and the consumers of this `IDatabase` schema depend on the actual schema. Thus, in that case swapping those implementations will cause the system to break, because the consumer (say `ManageUsersController` will call `this.database.Get()` to return a list of users, but if it is injected with the implementation for the "users databsae", the system will fail. This breaks LSP. – Steven Mar 19 '15 at 13:57

1 Answers1

0

This can be achieved by using the following configuration:

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        this.For<IUnitOfWork>().Use(new UnitOfWork("Connection1"));
        this.For<IDatabase2Service>().Use<Database2Service>().Ctor<IUnitOfWork>().Is(new UnitOfWork("Connection2"));
    }
}
Joseph Woodward
  • 9,191
  • 5
  • 44
  • 63