0

I have the following class at my business layer level (simplified code):

public class StatusUpdater : IStatusUpdater
{
   private readonly IStatusRepo _statusRepo;

   public class StatusUpdater(IStatusRepo statusRepo)
   {
      _statusRepo = statusRepo;
   }

   public voic UpdateStatus(int id, string newStatus)
   {
      _statusRepo.UpdateStatus(id,newStatus);
   }
}

So currently in the MVC side I'm using PerRequestLifetimeManager to control the lifetime of the DbContext.

But now in the windows service I can't use that, so I was going to do the following, but it doesn't feel right because it looks a lot like ServiceLocator :

using(var container = ConfiguredContainer.CreateChildContainer())
{
   var statusUpdater = container.Resolve<IStatusUpdater>();
   statusUpdater.UpdateStatus("test");
}

Are there any other options? and is there a way to use the same code in the MVC app and the windows service without having 2 types of registrations:

MVC:

container.RegisterType<IStatusRepo, StatusRepo>(new PerRequestLifetimeManager());

WindowsService:

container.RegisterType<IStatusRepo, StatusRepo>(new HierarchicalLifetimeManager());
SOfanatic
  • 5,523
  • 5
  • 36
  • 57
  • Not sure about `Unity` but in other DI frameworks you'd have to use different registration code for `MVC` and `Win Service` anyway. Direct calls to `Resolve` method always 'smell' as that's what DI frameworks are made for - to resolve instances when there's a need for that. When we call `.Resolve` method in our code it means that most likely we're doing something wrong. We can inject instances in constructor and change the life scope of the object that uses them instead. – Fabjan Apr 10 '17 at 16:19

1 Answers1

0

I usually register my types in their own assemblies, most likely like you did, but when there is something that's specific to the executing assembly, I override it in the registrations of that executing assembly.

// In BusinessProcessor
container.RegisterType<IBusinessProcessorA, MyBusinessProcessorA1>();
container.RegisterType<IBusinessProcessorA, MyBusinessProcessorA2>();
container.RegisterType<IBusinessProcessorB, MyBusinessProcessorB1>();

// In DataAccessLayer
container.RegisterType<IRepository, Repository<A>>("A", new HierarchicalLifetimeManager());
container.RegisterType<IRepository, Repository<B>>("B", new HierarchicalLifetimeManager());
container.RegisterType<IRepository, Repository<C>>("C", new HierarchicalLifetimeManager());

// In WindowsService
Register(BusinessProcessor);    // Call to have the BusinessProcessor register it's own things.
Register(DataAccessLayer);      // Call to have the DataAccessLayer register it's own things.
container.RegisterType<IService, MyService>();

// In WebApplication
Register(BusinessProcessor);    // Call to have the BusinessProcessor register it's own things.
Register(DataAccessLayer);      // Call to have the DataAccessLayer register it's own things.
container.RegisterType<IController, MyController>();
container.RegisterType<IRepository, Repository<A>>("A", new PerRequestLifetimeManager());

Another way could be to register repositories, in the DAL, with different named registrations, and do so for the BusinessProcessors, but that would mean your whole solution aware of that fact, which I would not recommend. At all.

Tipx
  • 7,367
  • 4
  • 37
  • 59