Inject same instance across several types

May 12, 2009 at 3:51 PM
Edited May 13, 2009 at 6:16 PM

Got it

 

Hi there

  Supose this case: i have an app layer and a busines layer. In my app layer i have a business process that uses rules and entities on my business layer.

  My goal is to have the app layer orchestrate transaction services with several rules(diferent types) in my business layer and, of course, the transaction has to be the same for all types. So, i want to inject the same

transaction service for every type. The BeginTransaction, Commit and Rollback should be managed in the app layer.

Any hints on how can i achieve this beahviour?

Thanx

May 22, 2009 at 10:58 AM

Hey folks, I'm searching for the exactly the same thing.

Suppose I have IRepository<T> interface and its implementation SqlRepository<T> that takes as an argument LINQ to SQL DataContext. Suppose as well that I have IService<T> interface and its implementation Services<T> that takes three IRepository<T1>, IRepository<T2> and IRepository<T3>. Demo code is below:

public interface IRepository<T> { }

public class SqlRepository<T> : IRepository<T>
{
    public SqlRepository(DataContext dc) { ... }
}

public interface IService<T> { }

public class Service<T,T1,T2,T3> : IService<T>
{
    public Service(IRepository<T1> r1, IRepository<T2>, IRepository<T3>) { ... }
}

Is it any way while creating Service class to inject all three repositories with the same DataContext?

Thanks in advande, it's really important for me!

May 23, 2009 at 12:28 AM

Hi

 

  I did found the answer for myself.

  In fact is very easy. You just instanciate the DataContext as Container Controled lifetime and inject it on you repositories.

  Unity will inject always the same instance and the same transaction(if that´s the case).

May 23, 2009 at 11:27 AM

Thanks for your suggestion,

but the problem here is that it will always use the same DataContext. That means, that different my users will have the same context and what is really show stopper for me - I'l be able to set LoadOptions only once :(

Any other ideas, please?

May 23, 2009 at 4:55 PM
I there
 
 Pheraps the container "containing" your data context would have to be application wide and then every time you need it you would have retrieve it from that container and inject it on your repository. In my case the containers are business process wide, that why i started to talk about application layer.
 
 
May 24, 2009 at 10:20 AM

I hope Unity DEVs and moderators will be able to help me.

May 24, 2009 at 6:53 PM

serioga,

Probably you can find a use for child containters here. Have your main container stored all other dependencies, and then for each new DataContext you can create child container, inject it there and use it.

May 24, 2009 at 8:07 PM

Asmi,

could you please provide some code snippets?

May 24, 2009 at 9:03 PM

Just to clarify what I want to accomplish. Calling:

var container = new UnityContainer();
var service = container.Resolve<IService>();

should be the same as:

var context = new DataContext();
var r1 = new Repository<T1>(context);
var r2 = new Repository<T2>(context);
var r3 = new Repository<T3>(context);
var service = new Service(r1, r2, r3);

The LifetimeManager in this case should be something like "PerObjectCreation".

Jun 16, 2009 at 6:02 AM
Edited Jun 16, 2009 at 6:03 AM

Sorry for late reply - just noticed new msg.

Code should be like that:

//do this once at app startup and then store this globalContainer somewhere
var globalContainer = new UnityContainer();
globalContainer.RegisterType<Repository<T1>, Repository<T1>>();
globalContainer.RegisterType<Repository<T2>, Repository<T2>>();
globalContainer.RegisterType<Repository<T3>, Repository<T3>>();
globalContainer.RegisterType<IService, ServiceImpl>();
//...

//when you need to instantiate service, do this:
//1. take globalContainer
var globalContainer = GetGlobalIoCContainer();
//2. create child container and put your data context in it
var contextContainer = globalContainer.CreateChldContainer();
contextContainer.RegisterInstance(new DataContext());

//3. instantiate service:
var service = contextContainer.Resolve<IService>();

/*no matter how much services you instantiate using that context container - 
they all will use one data context, but it will be created per-whatever basis - it depends on when you'll execute step 2*/
You should get what you wanna get.
Jun 18, 2009 at 5:11 AM

If you can't use ContainerControlledLifetimeManager, how about PerThreadLifetimeManager or HttpRequestLifetimeManager? You can see some examples here:

http://www.agileatwork.com/unit-of-work-with-unity-and-aspnet-mvc/