c# mvc DI ninject repository - c#

I am working with .net c# Mvc, using ninject repository pattern. My problem is that when developing I am using reusing in the functions, and everytime I want more info from db and need access to another table, I need to pass the repositories from all the places that are calling this function. Am I doing it wrong? ot this is the way, which is alot longer to develop then just opening a connection and disposing at the end of the function.

If your class needs to have loads of repositories passed in this can sometimes be a sign that your class is doing too many things and probably breaking the Single Responsibility Principle.
Perhaps if you broke this class into smaller more specialized classes the problem would not be so bad.
On the other hand, sometimes passing in loads of repositories is unavoidable. You might consider making a factory class that creates the class suffering from 'constructor jam' for you - this should save some typing as the hefty constructor initialization is just in one place (in the factory class).
edit: A really simple 'factory' class might be as follows:
public class FactoryClass
{
public ClassWithLotsOfRepositories GetClassWithLotsOfRepositories()
{
return new ClassWithLotsOfRepositories(new repository1(),
new repository2(), new repository3() );
}
}
So you can now create an instance of ClassWithLotsOfRepositories without having to specify the repositories in the constructor each time.
ClassWithLotsOfRepositories myClassThatUsesLotsOfRepositories = new FactoryClass().GetClassWithLotsOfRepositories();
My example has concrete classes passed in through the constructor. You are using Ninject so presumably have interfaces that need resolving - I'm just keeping this example simple to illustrate the concept.

use a unit of work the new up all of the repositories. That way you can pass in the uow into your controllers and have access to all repos when needed.

Related

CRUD operation for .net-core web API with interfaces - saveChanges() doesn't exist

Overview
I am making a .net-core web API with simple CRUD operations.
I have made the GET methods and got them up and running, however when I try to implement the Create method using dbContext.Add(myItem) I am not able to use dbContext.SaveChanges() afterwards.
My current work is available at:
https://github.com/petermefrandsen/TKD-theory-API
So far
I have tried adding a overwriting method to my database context.
Additionally I have tried adding the entity framework reference to the project.
As I do use interfaces for loose coupling I am at a loss when I comes to comparing with tutorials and other peoples similar problems. (read I am fairly new to c#).
Code
Controller:
[Route("dan/")]
[HttpPost]
public ActionResult<DanTheoryItem> PostDanTheoryItem(DanTheoryItem danTheoryItem)
{
_context.PostDanTheoryItem(danTheoryItem);
return new ActionResult<DanTheoryItem>(danTheoryItem);
}
IContext:
DanTheoryItem PostDanTheoryItem(DanTheoryItem danTheoryItem);
Context:
public DanTheoryItem PostDanTheoryItem(DanTheoryItem danTheoryItem)
{
var theoryItem = new DbDanTheoryItems
{
Id = danTheoryItem.Id,
KoreanTheoryItemId = danTheoryItem.KoreanTheoryItemId,
MainCategory = danTheoryItem.MainCategory,
SubCategory = danTheoryItem.SubCategory,
SubToSubCategory = danTheoryItem.SubToSubCategory,
NameLatin = danTheoryItem.NameLatin,
NamePhonetic = danTheoryItem.NamePhonetic,
NameAudio = danTheoryItem.NameAudio
};
_dbContext.DanTheoryItems.Add(theoryItem);
//_dbContext.SaveChanges();
return danTheoryItem;
}
Desired result
I'd like to have the controller call the context methods that will write the desired data to the database.
Your interface doesn't contain a SaveChanges method. Since you are using dependency injection only the methods in your interface will be available to your controller.
If you inherit from System.Data.Entity.IDbContext class in your custom interface, the method will be exposed to you in your controller.
Instantiating an instance of your DbLokisaurTKDTheoryAppContext class in your controller will expose the SaveChanges method as well.
It's hard to say exactly because you've neglected to post certain key portions of your code. However, my best guess is that you "context" is being provided IDbContext (of your own creating), instead of DbContext, and your interface doesn't define a SaveChanges method.
Honestly, just get rid of IDbContext. The point of an interface is to define a contract between multiple implementations. Here, there can be only one implementation: DbContext, and DbContext isn't even aware of this interface. Just inject your derived DbContext directly.
Using an interface isn't a magic wand. You have a hard dependency on Entity Framework here, so interface or not, you're tightly coupled. That's not necessary a bad thing though. EF is serving as your data layer, and this application is data driven; it's going to be tightly coupled to the data layer no matter what.
The API itself serves as your abstraction. Other layers will presumably just use the API, so no further abstraction is necessary, and in fact just adds more maintenance concern with no added benefit.

confusion in understanding of repository pattern

Im new in MVC pattern but im involved in a project which i am asked to implement repository pattern and unit of work,tons of examples online with 100 different implementations thats also a pain,because there is no clear way,any way,here is what i am doing and i would like you to give me a reason why should i use this damn pattern:
i have many controllers i instantiate the the model,and use it in my controller:
public CentralEntities DB = new CentralEntities();
i use it in my controller for example like this:
var turbineid = (from s in DB.MasterDatas
where s.name == turbinename
select new TrBineId
{
turbineID = s.m_turbine_id
}).Single();
TrBineId is my viewModel,any way the number of controllers are increasing and also in each controller i have many different LINQ,should i start with generic repository?
The damn reason to use repository pattern lies in implementing your solution with a clear separation of concerns and leverage domain I/O in a way that can be reused across your codebase.
You should start to revisit OOP and you'll need to double-check repository pattern.
At the end of the day, the need for certain patterns is already there, but it'll arise in your mind once you put the pieces in order.
I would start following some tutorial around the net about repository pattern to implement a proof-of-concept project and realize how it works.
Finally, Inversion of Control and Dependency Injection are concepts you'll need to manage to integrate your repositories and other patterns in your project to increase code composability and testability.
DISCLAMER: The following links are from my website about software architecture. You might want to check them as a possible reference implementation of repository pattern:
Repository
Agnostic repository
The repository pattern allows you to use the concept of Single responsibility principle, which mean (as an overview) one class = one role.
Your controler class is here for managing the request (Get, Post) and send back a response (FileResult, ActionResult...).
For the Data access (DAL, DAO) you will usually create a class per model entity (ClientRepository, CommandRepository), and you will create your methods for getting them (GetClients(), GetOneClientById(int id)...) within this class.
Edit for clarification after Matías comment:
This class will be called in your controller through his interface that you will also implement (with IOC or not).
You will then create a class instance of ClientRepository in your controller, but assigned to a reference of the interface type (IClientRepository).
**End Edit **
So we can imagin for Client Entity:
ClientController(All route for clients data)
IClientRepository (interface)
ClientRepository (Class which implement IClientRepository )
Then, in your controller you will call the repository like
IClientRepository clientRepo = new ClientRepository();
And then use the methods:
ICollection<Client> clients = clientRepo.YourMethod(int param1);
Advantages:
First of all, your code will be more clear and maintainable. Your DAO (DAL in .net) will keep the data access layer and you could use the GetAllClients method many time and you will not repeat yourself (DRY).
You can also apply easily some param on the method (like order, limit for pagination etc...)
It will be testable as well, I don't think that calling database in the controller can give you reasonable unit test results. You will also catch excption with a more "elegant way".
Small tip : When you will have more experience in the repo pattern, you could have a look at the Inversion of Control pattern

What is the point of dependency injection container? [duplicate]

This question already has answers here:
What is the difference between an interface and a class, and why I should use an interface when I can implement the methods directly in the class?
(16 answers)
Closed 5 years ago.
With .net core you can register "Services" which as I understand, simply means you can register types to concrete classes.
As such, I decided it's about time I learnt DI and practised it. I understand the concept, and with testing it is massively beneficial. However what confuses me is the idea of registering services and whether it's actually needed.
For example, if I have:
public class MyClass
{
public MyClass(IDataContext)
{
... store it
}
}
Then this means I can inject any class that implements the IDataContext, allowing for fakes and moqs in testing. But why would I register a service and map IDataContext to a concrete class in the startup? Is there something wrong with just using the following in other methods:
DataContext dc = new DataContext(); // concrete
var c = new MyClass(dc);
Edit
This question was around the point of using the container (services) rather than why use an interface in the constructor.
Now those classes where you put this code
public class MyService
{
public void DoSomething()
{
DataContext dc = new DataContext(); // concrete
var c = new MyClass(dc);
c.DoSomething();
}
}
have a hard dependency on DataContext and MyClass. So you can't test MyService in isolation. Classes shouldn't care how other classes do what they do, they should only care that they do what they say they're going to do. That's why we use interfaces. This is separation of concerns. Once you've achieved this, you can unit test any piece of code in isolation without depending on the behavior of outside code.
Registering your dependencies up front in one location is also cleaner and means you can swap dependencies out by changing one location instead of hunting down all the usages and changing them individually.
In my code example at the top, MyService requires the usage of both DataContext and MyClass. Instead, it should be like this:
public class MyService
{
private readonly IMyClass _myClass;
public MyService(IMyClass myClass)
{
_myClass = myClass;
}
public void DoSomething()
{
_myClass.DoSomething();
}
}
public interface IMyClass
{
void DoSomething();
}
public class MyClass : IMyClass
{
private readonly IDataContext _context;
public MyClass(IDataContext context)
{
_context = context;
}
public void DoSomething()
{
_context.SaveSomeData();
}
}
Now MyService isn't dependent on DataContext at all, it doesn't need to worry about it because that's not its job. But it does need something that fulfills IMyClass, but it doesn't care how it's implemented. MyService.DoSomething() can now be unit tested without depending on the behavior of other code.
If you weren't using a container to handle satisfying the dependencies, then you're probably introducing hard dependencies into your classes, which defeats the entire point of coding against an interface in the first place.
Testing in isolation is important. It's not a unit test if you're testing more than one finite piece of code. It's an integration test (which have their own value for different reasons). Unit tests make it quick and easy to verify a finite block of code works as expected. When a unit test isn't passing, you know right where the problem is and don't have to search hard to find it. So if a unit test depends on other types, or even other systems (likely in this case, DataContext is specific to a particular database) then we can't test MyService without touching a database. And that means the database must be in a particular state for testing, which means the test likely isn't idempotent (you can't run it over and over and expect the same results.)
For more information, I suggest you watch Deep Dive into Dependency Injection and Writing Decoupled Quality Code and Testable Software by Miguel Castro. The best point he makes is that if you have to use new to create an instance of an object, you've tightly coupled things. Avoid using new, and Dependency Injection is a pattern that enables you to avoid it. (using new isn't always bad, I'm comfortable with using new for POCO models).
You can inject your dependencies manually. However this can get a very tedious task. If your services get bigger, you will get more dependencies, where each dependency on its own can have multiple dependencies.
If you change your dependencies, you need to adjust all usages. One of the main advantages of a DI container is, that the container will do all dependency resolving. No manual work required. Just register the service and use it wherever you want and how often you want.
For small projects this seems like too much overhead, but if your project grows a little, you will really appreciate this.
For fixed dependencies, which are strongly related and not likely to change, injecting them manually is fine.
Using a DI container has another advantage. The DI container will control the life cycle of its services. A service could be a singleton, transient (each request will get a new instance) or have scoped life time.
For example, if you have a transactional workflow. The scope could match the transaction. While in the transaction, requests to a service will return the same instance.
The next transaction will open a new scope and therefore will get new instances.
This allows you to either discard or commit all instances of one transaction, but prevents that following transaction uses resources from the previous one.
You right, you can create all instances manually. In small projects it's an usual practice. The place in your project where links the classes is called Composition Root, and what you do is Constructor Injection.
IoC-libraries can simplify this code, especially considering complex cases like life-time scopes and group registration.
Inversion of control (of constructing an object)
The idea of this pattern is when you want to construct an object you only need to know about the type of the object and nothing about its dependencies or parameters.
Dependency injection
This pattern is taking the inversion of control pattern a step further by enabling you to directly inject an object into a constructor for example.
Again you only need to know the type of the object you want to get and the dependency container will inject an object.
You also don't need to know if a new object is constucted or if you get a allready existing reference.
The most common used type of dependency injection is constructor injection but you could inject your type into other places like methods.
Seperation of concerns
Generally you register a type by an interface to get rid of the dependency on the type.
This is very helpfull for mocking types when testing and it helps to use the open closed principle.
Martin Fowler on "Inversion of Control Containers and the Dependency Injection pattern".

Architecture to avoid creating repositories inside testable methods

Working on an MVVM application. Each ViewModel class has a constructor which accepts a Repository class so that it can be mocked out for unit testing.
The application is designed to be operated across several windows at once. So it contains a number "View" or "Open" style methods which create new ViewModels and place them into new windows. Because these are triggered via the UI, they are often inside existing ViewModels. For instance:
public void ViewQuote(Quote quote)
{
if (quote.CreatedOn == null)
{
quote.CreatedOn = DateTime.Now;
}
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, new Repository()));
}
Now, that flow control statement looks worth testing to ensure that quotes passed with a null CreatedOn date get assigned one. However, my test for this fails because although the parent ViewModel has a mocked Repository, the NewWindow method spins up a new ViewModel with a real-life Repository inside it. This then throws an error when it's used inside the constructor of that class.
There are two obvious options.
One is to pull out the date assignment into a stand-alone function to test. That'll work, but it seems too simplistic for its own function. Plus if I do it all over the application it risks creating too much fragmentation for easy readability.
The other is to somehow change the constructor code for ViewModels to not use the Repository directly. That might be an option here, but it's unlikely to be workable for every possible scenario.
Or is there a third way to design this better so I can pass a mocked Repository into the constructor of my new ViewModel?
Newing up services (or service-like objects such as repositories) is a design smell. And the problems that you're experiencing are the consequence.
In other words, you are lacking a clear and well-defined Composition Root.
Solution: Use proper dependency injection
The only clean solution to this is to inject services through the constructor. Repositories usually have a shorter lifecycle than the application itself, so in this case you would inject a factory that is able to create the repository.
Note that clear dependency trees are good design, but using a DI framework such as Autofac is only one technical solution to implement such a design. You can completely solve your problems and create a clean composition root without using a DI framework.
So although this is probably a lot of work, you should redesign your application to have a clear composition root. Otherwise, you will run into small issues over and over again, especially in the testing area.
You could work around it by adding a public Repository NewRepository property, in your ViewQuote method change it to look like this:
public void ViewQuote(Quote quote)
{
if (quote.CreatedOn == null)
{
quote.CreatedOn = DateTime.Now;
}
if(NewRepository == null) NewRepository = new Respository();
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, NewRepository));
}
Then in your mock, just ensure that the public NewRepository property is assigned to before the test is run on that bit of code.
Not very elegant, but it would require the least amount of changing in my opinion.

Trying to simplify our repository pattern

Currently we have implemented a repository pattern at work. All our repositories sit behind their own interfaces and are mapped via Ninject. Our project is quite large and there are a couple quirks with this pattern I'm trying to solve.
First, there are some controllers where we need upwards of 10 to 15 repositories all in the same controller. The constructor gets rather ugly when asking for so many repositories. The second quirk reveals itself after you call methods on multiple repositories. After doing work with multiple repositories we need to call the SaveChanges method, but which repository should we call it on? Every repository has one. All repositories have the same instance of the Entity Framework data context injected so picking any random repository to call save on will work. It just seems so messy.
I looked up the "Unit Of Work" pattern and came up with a solution that I think solves both problems, but I'm not 100% confident in this solution. I created a class called DataBucket.
// Slimmed down for readability
public class DataBucket
{
private DataContext _dataContext;
public IReportsRepository ReportRepository { get; set; }
public IEmployeeRepository EmployeeRepository { get; set; }
public IDashboardRepository DashboardRepository { get; set; }
public DataBucket(DataContext dataContext,
IReportsRepository reportsRepository,
IEmployeeRepository employeeRepository,
IDashboardRepository dashboardRepository)
{
_dataContext = dataContext;
this.ReportRepository = reportsRepository;
this.EmployeeRepository = employeeRepository;
this.DashboardRepository = dashboardRepository;
}
public void SaveChanges()
{
_dataContext.SaveChanges();
}
}
This appears to solve both issues. There is now only one SaveChanges method on the data bucket itself and you only inject one object, the data bucket. You then access all the repositories as properties. The data bucket would be a little messy looking since it would be accepting ALL (easily 50 or more) of our repositories in its constructor.
The process of adding a new repository would now include: creating the interface, creating the repository, mapping the interface and repository in Ninject, and adding a property to the data bucket and populating it.
I did think of an alternative to this that would eliminate a step from above.
public class DataBucket
{
private DataContext _dataContext;
public IReportsRepository ReportRepository { get; set; }
public IEmployeeRepository EmployeeRepository { get; set; }
public IDashboardRepository DashboardRepository { get; set; }
public DataBucket(DataContext dataContext)
{
_dataContext = dataContext;
this.ReportRepository = new ReportsRepository(dataContext);
this.EmployeeRepository = new EmployeeRepository(dataContext);
this.DashboardRepository = new DashboardRepository(dataContext);
}
public void SaveChanges()
{
_dataContext.SaveChanges();
}
}
This one pretty much eliminates all the repository mappings in Ninject because they are all instantiated in the data bucket. So now the steps to adding a new repository include: Create interface, create repository, add property to data bucket and instantiate.
Can you see any flaws with this model? On the surface it seems much more convenient to consume our repositories in this way. Is this a problem that has been addressed before? If so, what is the most common and/or most efficient approach to this issue?
First, there are some controllers where we need upwards of 10 to 15 repositories all in the same controller.
Say hello to Abstract factory pattern. Instead of registering all repositories in Ninject and injecting them to controllers register just single implementation of the factory which will be able to provide any repository you need - you can even create them lazily only if the controller really needs them. Than inject the factory to controller.
Yes it also has some disadvantages - you are giving controller permission to get any repository. Is it problem for you? You can always create multiple factories for some sub systems if you need or simply expose multiple factory interfaces on single implementation. It still doesn't cover all cases but it is better than passing 15 parameters to constructor. Btw. are you sure those controllers should not be split?
Note: This is not Service provider anti-pattern.
After doing work with multiple repositories we need to call the SaveChanges method, but which repository should we call it on?
Say hello to Unit of Work pattern. Unit of Work is logical transaction in your application. It persists all changes from logical transaction together. Repository should not be responsible for persisting changes - the unit of work should be. Somebody mentioned that DbContext is implementation of Repository pattern. It is not. It is implementation of Unit of Work pattern and DbSet is implementation of Repository pattern.
What you need is central class holding the instance of the context. The context will be also passed to repositories because they need it to retrieve data but only the central class (unit of work) will offer saving changes. It can also handle database transaction if you for example need to change isolation level.
Where should be unit of work handled? That depends where your logical operation is orchestrated. If the operation is orchestrated directly in controller's actions you need to have unit of work in the action as well and call SaveChanges once all modifications are done.
If you don't care about separation of concerns too much you can even combine unit of work and factory into single class. That brings us to your DataBucket.
I think you are absolutely right to use the Unit of Work pattern in this case. Not only does this prevent you from needing a SaveChanges method on every repository, it provides you a nice way to handle transactions from within code rather than in your database itself. I included a Rollback method with my UOW so that if there was an exception I could undo any of the changes the operation had already made on my DataContext.
One thing you could do to prevent weird dependency issues would be to group related repositories on their own Unit of Work, rather than having one big DataBucket that holds every Repository you have (if that was your intent). Each UOW would only need to be accessible at the same level as the repositories it contained, and other repositories should probably not depend on other UOWs themselves (your repositories shouldn't need to use other repositories).
If wanted to be an even bigger purist of the pattern, you could also structure your UOWs to represent just that, a single Unit of Work. You define them to represent a specific operation in your domain, and provide it with the repositories required to complete that operation. Individual repositories could exist on more than one UOW, if it made sense to be used by more than one operation in your domain.
For example, a PlaceCustomerOrderUnitOfWork may need a CustomerRepository, OrderRepository, BillingRepository, and a ShippingRepository
An CreateCustomerUnitOfWork may need just a CustomerRepository. Either way, you can easily pass that dependency around to its consumers, more fine grained interfaces for your UOW can help target your testing and reduce the effort to create a mock.
The notion of every repository having a SaveChanges is flawed because calling it saves everything. It is not possible to modify part of a DataContext, you always save everything. So a central DataContext holder class is a good idea.
Alternatively, you could have a repository with generic methods that can operate on any entity type (GetTable<T>, Query<T>, ...). That would get rid of all those classes and merge them into one (basically, only DataBucket remains).
It might even be the case that you don't need repositories at all: You can inject the DataContext itself! The DataContext by itself is a repository and a full fledged data access layer. It doesn't lend itself to mocking though.
If you can do this depends on what you need the "repository" do provide.
The only issue with having that DataBucket class would be that this class needs to know about all entities and all repositories. So it sits very high in the software stack (at the top). At the same time it is being used by basically everything so it sits at the bottom, too. Wait! That is a dependency cycle over the whole codebase.
This means that everything using it and everything being used by it must sit in the same assembly.
What I have done in the past was to create child injection containers (I was using Unity) and register a data context with a ContainerControlledLifetime. So that when the repositories are instantiated, they always have the same data context injected into them. I then hang on to that data context and when my "Unit of Work" is complete, I call DataContext.SaveChanges() flushing all the changes out to the database.
This has some other advantages such as (with EF) some local caching, such that if more than one repository needs to get the same entity, only the first repository actually causes a database round trip.
It's also a nice way to "batch up" the changes and make sure they execute as a single atomic transaction.

Categories

Resources