Question

I have lots of repositories like this:

public class PersonRepository : IPersonRepository
{
    private readonly IUnitOfWork _unitOfWork;

    public PersonRepository(IUnitOfWork instance)
    {
        _unitOfWork = instance;
    }

    //Remove, Get methods...
    public void Add(Person p)
    {
        _unitOfWork.Context.People.Add(p);
    }
}

and Unit of work class like this:

public class UnitOfWork : IUnitOfWork, IDisposable
{
    public UnitOfWork(){ }

    private readonly HezarehContext _context = new HezarehContext();
    public HezarehContext Context
    {
        get
        {
            return _context;
        }
    }

    public int Save()
    {
        return _context.SaveChanges();
    }

    public void Initialize()
    {
        Context.Database.Initialize(false);
    }

    #region IDisposable Members

    public void Dispose()
    {
        _context.Dispose();
    }

    #endregion
}

Now i want each time my ViewModels gets resolved, a new IUnitOfWork instantiated. Most of my ViewModels are like this:

public class PeopleMainViewModel : NotificationObject
{
    // both of repositories must have same instance of IUnitOfWork
    private readonly IPersonRepository _personRepository = ServiceLocator.Current.GetService<IPersonRepository>();
    private readonly ICategoryRepository _categoryRepository = ServiceLocator.Current.GetService<ICategoryRepository>();

    public PeopleMainViewModel()
    {
        InitializeView();
    }

    // add, edit, remove commands ...
}

ViewModels always gets resolved using Unity Container like this:

Container.RegisterType<IPersonRepository, PersonRepository>();
// resolve in InjectionProperty...
Container.RegisterType<Object, PeopleMainView>("PeopleMainView", new InjectionProperty(PeopleMainView.DataContextProperty.Name, Container.Resolve<PeopleMainViewModel>();

And my question is, How and Where i Register my ViewModels and IUnitOfWork to have IUnitOfWork instance for each of them?

Was it helpful?

Solution 2

Update: There is another solution here in unity.codeplex discussions.

I finally found a solution. There is a feature in Unity container that let you pass parameters while resolving a Type. by changing constructor of ViewModels to this:

public class PeopleMainViewModel : NotificationObject
{
    private readonly IPersonRepository _personRepository = null;
    private readonly ICategoryRepository _categoryRepository = null;

    public PeopleMainViewModel(IUnityContainer container, IUnitOfWork unitOfWork)
    {
        // now both of repositories have same instance of IUnitOfWork
        _personRepository = container.Resolve<IPersonRepository>(new ParameterOverride("unitOfWork", unitOfWork));
        _categoryRepository = container.Resolve<ICategoryRepository>(new ParameterOverride("unitOfWork", unitOfWork));
        InitializeView();
    }

    // add, edit, remove commands ...
}

problem solved. now _personReposiotry and _categoryRepository have reference to same instance of unitOfWork.

OTHER TIPS

If I understand your question, just register your IUnitOfWork the same way (and same place) you register the repository in your above example. You don't need to register your ViewModels based on your current design since you aren't using an Interface.

Container.RegisterType<IUnitOfWork, UnitOfWork>();

And continue to have your repositories accept the IUnitOfWork in the constructor. This will allow Unity to use constructor injection to provide a new instance of IUnitOfWork each time it resolves a repository. By default, you'll get a new instance of the IUnitOfWork each time. If you'd like to have a singleton IUnitOfWork, you would have to say so when you register the IUnitOfWork like this:

Container.RegisterType<IUnitOfWork, UnitOfWork>(new ContainerControlledLifetimeManager());

If you want to read up on Lifetime Managers, you can do so here.

I would also recommend changing your ViewModels to take the repositories in as Constructor Parameters, like this if you are going to Resolve them (so Unity will do the work without you referencing the ServiceLocator directly)

public PeopleMainViewModel(IPersonRepository personRepo, ICategoryRepository categoryRepo)
{
...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top