1

I am working with asp.net mvc 5 project. suppose i am showing Customer data where i am showing customer detail and customer favorite products.

so i fetch data from customer repository, country repository and favorite repository.

many time people write article on injection repository by unity DI. when i am working with single repository then this concept make sense but when i have to fetch data from multiple repositories then how could i inject multiple repositories in mvc controller ctor by unity di?

see a small code for injecting repository by unity DI.

public class FooController : Controller  
{  
     readonly IFooRepository _repository;  

     // Inject here  
     public ProductController(IFooRepository repository)  
     {  
           _repository = repository;   
     }  

     // Use it here  
     public ActionResult Bar()  
     {  
          var bar = _repository.DoSomething();  
     }  
}  

above code refer from https://forums.asp.net/t/2105895.aspx?Repository+inject+into+controller+by+Unity+DI

now tell me how could i refactor my code or what approach i should follow as a result i can work with multiple repositories and also can inject by Unity DI.

please give me best guidance. thanks

Mist
  • 684
  • 9
  • 30

2 Answers2

1

Just add any dependency you require into the controller's constructor.

public class FooController : Controller  
{  
    readonly IFooRepository _repository;  
    readonly IOtherRepository _otherRepository;  

    public ProductController(IFooRepository repository, IOtherRepository otherRepository)  
    {  
        _repository = repository;   
        _otherRepository = otherRepository;
    }  
L-Four
  • 13,345
  • 9
  • 65
  • 109
0

Please note that while L-Four's response is a often a good way to go, you might run into difficulties later when you did some modification to loaded entities and want to save them, as you probably ended up having separate DBContext instances inside of your repositories. But it depends on your Repository and DI implementation and configuration...

Example:

// Assume you want to create a new User with associated Account

var user = _usersRepository.AddUser(new User(....));
var account = _accountRepository.AddAccount(new Account{ ... User = user });

// Now you want to save them both in one transaction... how?
_usersRepository.Commit();
_accountRepository.Commit(); // What if this fails? you have an orphaned user?

To solve this problem, I'd recommend implementing the so called Unit Of Work pattern. There are some good examples also on Stack Overflow and elsewhere.

Might save you some headache for later.

Your updated code will be:

public class FooController : Controller  
{  
     readonly IUsersAndAccountUnitOfWork _uow;  

     // Inject here  
     public ProductController(IUsersAndAccountUnitOfWork uow)  
     {  
           _uow = uow;
     }  

     // Use it here  
     public ActionResult Bar()  
     {  
           var user = _uow.Users.AddUser(new User(....));
           var account = _uow.Accounts.AddAccount(new Account{ ... User = user });

           _uow.Commit();
     }  
} 
thmshd
  • 5,729
  • 3
  • 39
  • 67
  • 1
    You could simply register the db context in such a way that only one instance exists and that it only lives in the scope of the specific (web) request. – L-Four Feb 15 '18 at 14:31
  • @L-Four Yes! but it's good to have a single `Commit` method. If it's on Repository level, I'd expect it to actually apply to that Repository only, e.g. `userRepository.Commit()` should commit my changes to Users only, I don't want it to also Commit changes in `myOtherRepository`. – thmshd Feb 15 '18 at 15:28
  • @thmshd would you please post a small complete sample code just to show the flow of your code? did you use any DI to map between IRepository and Repository for automatic passing to controller? – Mist Feb 16 '18 at 08:06
  • I would not expose commits in repositories. The context is created and destroyed independent of repositories, and passed to the repositories as a dependency for example. – L-Four Feb 16 '18 at 08:15
  • @L-Four I wouldn't expose commits in repositories either, I don't understand how your attempt is to commit multiple changes done across multiple repositories, at once. Where does your `Commit` method sit, who is responsible to execute `Commit` on the DbContext? Surely, you don't want every single `AddXYZ(...)` method to commit, and you need to control that because you might need the new Entity IDs for further processing. This is where the _Unit Of Work_ pattern comes into play. – thmshd Feb 16 '18 at 13:03
  • @Mist Follow this Microsoft tutorial: [__Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application__](https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application) to learn about the patterns... Repository and Unit Of Work often go hand-in-hand – thmshd Feb 16 '18 at 13:08