0

I have a repository RepositoryDepartment which takes DbContext (i.e. AdventureworksDB) as a constructor parameter.

public class RepositoryDepartment : Repository<Department>, IRepositoryDepartment
{
    AdventureWorksDB _ctx;

    public RepositoryDepartment(AdventureWorksDB dataContext)
        : base(dataContext)
    {
        _ctx = dataContext;
    }

I have mapped the public interface IRepositoryDepartment : IRepository<Department> to RepositoryDepartment using Unity DI.

So when I resolve the IRepositoryDepartment interface like this:

Container.Resolve<IRepositoryDepartment>()

I get a fully functional RepositoryDepartment Object. But the question here is: How does the AdventureworksDB constructor parameter get instantiated, as I didn't register the type nowhere??? The base class only gets the object, it has no instantiation logic! Can someone explain the magic that happens here!?

Legends
  • 21,202
  • 16
  • 97
  • 123

1 Answers1

0

There is absolutely no magic. The context is a concrete class, if it is not registered for a specific lifetime, Unity just creates an instance using a public constructor with maximum number of parameters.

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • 1
    Didn't know that, hmmm. I thought only registered types/interfaces get instantiated. But how can I dispose the DbContext now? Do I have to offer a reference to the DbContext as a property from the repository? Cause if I would do it without DI, I would create a DbContext using a using block and inside of that block I would instantiate the repository and pass the dbcontext to the constructor. – Legends Jul 30 '13 at 23:02
  • @Legends: Take a look at the concept of scoped lifetime. For unity there are lifetime managers such as `HttpContextLifetimeManager` and `PerResolveLifetimeManager`. I would expect the `HttpContextLifetimeManager` to dispose instances, but other lifetime managers don't dispose or dispose [when the container gets disposed](http://stackoverflow.com/questions/5129789/unity-2-0-and-handling-idisposable-types-especially-with-perthreadlifetimemanag). – Steven Jul 31 '13 at 07:23
  • This is exactly as @Steven explains - as long as the lifetime manager resolves the same instance, there is no point in disposing it. When the lifetime ends, you can dispose manually. For example, if you use the `PerHttpContextLifetimeManager`, the same `DbContext` is returned during http context. And then, at the end, in the `EndRequest` you can resolve once again and dispose it. – Wiktor Zychla Jul 31 '13 at 07:29
  • Which is a bit an unfortunate design of Unity. You will have to dispose manually and will have to resolve everything just to dispose it, which may cause types to be created just for the sake of disposing them (since not might not need every disposable type in each request). – Steven Jul 31 '13 at 09:22
  • @Steven: true. We work this around by registering contexts with an injection factory which "manually" controls the lifetime using the `HttpContext.Current.Items` container. This way, upon disposal, we can test whether or not the container contains the context (= whether or not the context has been created). – Wiktor Zychla Jul 31 '13 at 09:56
  • I am using transient for close to everything. I have implemented IDisposable in my IRepository:IDisposable. Now I can use my RepositoryX in a using block, as I don't want to wait for DbContext to be disposed somewhen, somehow.... So I need to manually dispose it, as the container has no sense about my transient object, right ?! – Legends Jul 31 '13 at 10:04
  • Right, if no one disposes the context, it will not be disposed. You have to dispose manually. BTW, transient context are not necessary in a web application, the `PerHttpContext` manager is probably more appropriate. – Wiktor Zychla Jul 31 '13 at 10:07
  • It's a Wcf Service actually. And I use the buildin Wcf Lifetime Managment: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]. Only the instantiation is done via Unity. – Legends Jul 31 '13 at 10:48
  • A good explanation of built-in lifetime managers can be found here: [unity-build-in-lifetime-managers/](http://www.ladislavmrnka.com/2011/03/unity-build-in-lifetime-managers/) – Legends Jul 31 '13 at 11:12
  • The `InstanceContextMode.PerCall` tells what is the lifetime of the wcf service class. It doesn't have anything to do with the lifetime of the dbcontext. If you need the `PerHttpContextLifetimeManager`, grab one from somewhere, for example http://netpl.blogspot.com/2013/03/unity-and-http-per-request-lifetime.html – Wiktor Zychla Jul 31 '13 at 11:37
  • Absolutely clear, this is what I said. So transient fits for my purposes regarding DbContext and IRepositoryX instantiation. Thanks. – Legends Jul 31 '13 at 13:06