I have a plan to rework my company web publishing platform with dependency injection because the coding references start to become a bit more complex.
In my research I have found a lot of examples regarding MVC but our intention at the moment is to rework the web platform's Business logic, DAL, Core etc.. with minimal UI interventions.
The architecture of the web platform is the following
SQL database
DAL (EF6)
Separated model from dal (poco)
Business Logic
CMS System
Front end (websites)
All in all separated projects with their own concerns but heavily referenced in between.
In my research to counteract heavy referencing and coupling I have chosen and followed the following example
techbrij blog post
I do understand the concepts of abstraction and dependency injection well and have set up a test project but hit a snag.
In MVC the instantiating new data class (poco) is handled by the ActionResult
// POST: /Country/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Country country)
{
// TODO: Add insert logic here
if (ModelState.IsValid)
{
_CountryService.Create(country);
return RedirectToAction("Index");
}
return View(country);
}
so far so good if we use MVC. But if I use Webforms in order to insert new record my logic says that i need to instantiate a new class from the model fill its properties with specific values and pass it to the BLL/DAL or service layer:
public void InsertRecord()
{
Country country = new Country();
country.Name = "Some Country"; // or value from textbox..
_CountryService.Create(country);
}
My question is:
Regarding webforms, is this OK or do I need to absrtact the model in order to inject the new data class without the "new" keyword
Since using the "new" keyword will not decouple my data model, how would you do this to achieve decoupling/ioc/di?
I think that's fine. All the MVC framework is doing is newing up an instance of Country and matching up request parameters to your model's properties. You might find a library that does the same in webforms but it would probably be overkill.
You could use a factory to abstract away the newing up but it's probably not for situations like you have here.
Take a look at this article. It differentiates between Injectables and Newables.
In my understanding, Injectables are classes that present behavior that you want to vary using DI. While Newables are simple classes that mostly contain data. They might contain some behavior that is internal to these classes (does not require external services to work) so you don't want to change such behavior using DI.
It seems to me that the Country class is a Newable. Therefore, it is perfectly normal to new it up via new.
The link you provided use repository pattern, I personally run away from it because it is all about hide your persistence tools, and if you hide your arsenal you lose the power it provides, apart from the probably unnecessary added complexity.
That said it is ok to manually create entities with new keywords, as long as you don't do it in the user interface class, for web forms you can use Model View Presenter combined with modern Model Binding technics available for Asp.NET Web Forms. Presenter instantiate entities and interacts with persistent mechanisms (EF in your case).
You can decouple UI code from presentation code, presenter can lives in its own assembly and works with View Interfaces so you will inject concrete implementations with IoC.
Here is a very basic sample skeleton for a sample infrastructure representing the above:
public interface IView{}
public abstract Presenter<T> where T : IView
{
public Presenter( T view){ View = view;}
public T View {get;set;}
}
The services I build are about encapsulating Business Logic, Application Logic, etc. Again, you will want have to avoid hard references to concrete implementations of those services by working with interfaces and injecting concrete implementations with some IoC.
Related
This question already has an answer here:
Dependency Injection into Entity Class
(1 answer)
Closed last month.
I am using EF Core 3.1 and have several custom services provided via dependency injection, e.g., an ILogger. How can these services be resolved from within a model, such as when I want to log something from the model?
Adding the dependency to the constructor (like in other classes) means that an empty constructor would not work... which is what is used in all the EF Core examples I can find:
new Author{ FirstName = "William", LastName = "Shakespeare" };
... which suggests DI in a model constructor would be an anti-pattern.
But since models do not inherit, I'm not sure how to get my hands on the other services at runtime (other than a hack like saving a static reference to IServiceProvider from the Startup class).
One might argue that models should not contain business logic, and therefore do not need access to services. However, the problem remains — there are times I need to do things with a model that are not triggered by a web request / controller (and therefore, I have no access to the DI services).
Edit: the scenario is actually more complex than a simple logger.
A simplified example of where else I need services looks like this (assuming a I18n service):
public string Name => GetService<I18n>().Localize(this.translationKey);
The model in this case might be rendered into JSON for the client.
Trying to put this localization code in the Controller or other service seems like a road to copy-pasta spaghetti code. The Name property is required in many different cases, not just a single controller path. For example, it might be concatenated into another localized string elsewhere. Being forced to do the name localization explicitly from outside the model would be extremely repetitive and burdensome, especially once this example was scaled out to the scope of my app.
I could come up with many more such examples unrelated to logging or I18n.
Another example: how would I know the DbContext from which the Model was loaded? An app with two databases like mine can easily lose track of this lineage. It seems right now the controller which created the model needs to track this explicitly, whereas if models supported DI they would be able to capture the DbContext in the constructor.
As per this question and discussion in comments, this is possible, but not recommended.
From MSDN:
Injecting the DbContext like this is often considered an anti-pattern since it couples your entity types directly to EF Core. Carefully consider all options before using service injection like this.
If this is not a problem for you, then we can inject to our entities like this:
private IInjectedService _service;
private Entity(IInjectedService service)
{
EnsureArg.IsNotnull(service, nameof(service));
_service = service;
}
This is generally frowned upon, and normally we would inject those services into the caller (e.g. QueryHandler or Service)
In my project, I use entity framework 7 and asp.net mvc 6 \ asp.net 5. I want to create CRUD for own models
How can I do better:
Use dbcontext from the controller.
In the following link author explain that this way is better, but whether it is right for the controllers?
Make own wrapper.
The some Best practices write about what is best to do own repository.
I'm not going to change the ef at something else, so do not mind, even if there is a strong connectivity to access data from a particular implementation
and I know that in ef7 dbcontext immediately implemented Unit Of Work and Repository patterns.
The answer to your question is primarily opinion-based. No one can definitively say "one way is better than the other" until a lot of other questions are answered. What is the size / scope / budget of your project? How many developers will be working on it? Will it only have (view-based) MVC controllers, or will it have (data-based) API controllers as well? If the latter, how much overlap will there be between the MVC and API action methods, if any? Will it have any non-web clients, like WPF? How do you plan to test the application?
Entity Framework is a Data Access Layer (DAL) tool. Controllers are HTTP client request & response handling tools. Unless your application is pure CRUD (which is doubtful), there will probably be some kind of Business Logic processing that you will need to do between when you receive a web request over HTTP and when you save that request's data to a database using EF (field X is required, if you provide data for field Y you must also provide data for field Z, etc). So if you use EF code directly in your controllers, this means your business processing logic will almost surely be present in the controllers along with it.
Those of us who have a decent amount of experience developing non-trivial applications with .NET tend to develop opinions that neither business nor data access logic should be present in controllers because of certain difficulties that emerge when such a design is implemented. For example when you put web/http request & response logic, along with business logic and data access logic into a controller, you end up having to test all of those application aspects from the controller actions themselves (which is a glaring violation of the Single Responsibility Principle, if you care about SOLID design). Also let's say you develop a traditional MVC application with controllers that return views, then decide you want to extend the app to other clients like iOS / android / WPF / or some other client that doesn't understand your MVC views. If you decide to implement a secondary set of WebAPI data-based controller actions, you will be duplicating business and data access logic in at least 2 places.
Still, this does not make a decision to keep all business & data-access logic in controllers intrinsically "worse" than an alternate design. Any decision you make when designing the architecture of a web application is going to have advantages and disadvantages. There will always be trade-offs no matter which route you choose. Advantages of keeping all of your application code in controllers can include lower cost, complexity, and thus, time to market. It doesn't make sense to over-engineer complex architectures for very simple applications. However unfortunate, I have personally never had the pleasure of developing a simple application, so I am in the "general opinion" boat that keeping business and data access code in controllers is "probably not" a good long-term design decision.
If you're really interested in alternatives, I would recommend reading these two articles. They are a good primer on how one might implement a command & query (CQRS) pattern that controllers can consume. EF does implement both the repository and unit of work patterns out of the box, but that does not necessarily mean you need to "wrap" it in order to move the data access code outside of your controllers. Best of luck making these kinds of decisions for your project.
public async Task<ActionResult> Index() {
var user = await query.Execute(new UserById(1));
return View(user);
}
Usually I prefer using Repository pattern along with UnitOfWork pattern (http://www.asp.net/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) - I instantiate DbContext in an UnitOfWork instance object and I inject that DbContext in the repositories. After that I instantiate UnitOfWork in the controller and the controller does not know anything about the DbContext:
public ActionResult Index()
{
var user = unitOfWork.UsersRepository.GetById(1); // unitOfWork is dependency injected using Unity or Ninject or some other framework
return View(user);
}
This depends on the lifecycle of your application.
If it will be used, extended and changed for many years, then I'd say creating a wrapper is a good choice.
If it is a small application and, as you have said, you don't intend to change EntityFramework to another ORM, then spare yourself the work of creating a wrapper and use it directly in the controller.
There is no definite answer to this. It all depends on what you are trying to do.
If you are going for code maintainability I would suggest using a wrapper.
I've been trying to learn how the service layer and repository pattern work. So far I've written a service layer and a simple repository pattern interface. However, I often see articles stating that the repository pattern allows for being able to swap in and out different data stores without the consuming code having to be changed.
In my case I want to be able to support reading and writing the application data to CSV and/or XML files. This is the part where I do not understand how to properly implement this with the repository pattern. Should I have a repository per data store?
ProductCsvRepository : IProductRepository
ProductXmlRepository : IProductRepository
However if I do this then the service layer would have to be aware of the underlying data store, which breaks the idea of being able to easily swap in and out different data stores.
Would I then have to have a service layer that looks like this?
private readonly IProductXmlRepository _productXmlRepository;
private readonly IProductCsvRepository _productCsvRepository;
public ProductService()
{
_productXmlRepository = new IProductXmlRepository();
_productCsvRepository = new IProductCsvRepository();
}
public ICollection<Product> GetAllXml()
{
return _productXmlRepository.GetAllCsv();
}
public ICollection<Product> GetAll()
{
return _productCsvRepository.GetAllXml();
}
This then raises two questions:
Surely this then breaks the idea of the consuming code needing to know what the data store is?
What about in the situations where the consuming code does need to know about the data store, such as for "File > Export As" type functionality? Should export functionality actually be a different service that utilises the appropriate CSV or XML service?
I think I am definetly not understanding how to correctly implement a repository patten and a service layer. How should I actually design repository patten and service layer?
Take a look at dependency injection and the plug-in pattern. They support injecting a concrete implementation of a repository. Your service layer then has only one reference to IProductRepository and a concrete repository gets injected. Something along the lines of this:
public class ProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
}
public class ConsumingClass {
{
private readonly IProductService _productService = new ProductService(new ProductXmlRepository());
// methods to use the the product service
}
But better would be to use a inversion of control container like NInject or SimpleInjector. Those frameworks can be used to link abstract classes (IProductRepository) to concrete classes (ProductXmlRepository or ProductXmlRepository) based on xml configurations.
Your application's solution should be structured following the Dependency Inversion Principle (http://deviq.com/dependency-inversion-principle/), so that there are at minimum three projects:
Core
Infrastructure
Your UI project
All (or nearly all) of your interfaces should be declared in Core (e.g. IProductRepository). Your interface implementations belong in Infrastructure, which references Core. Finally, your UI project should reference Core, but not necessarily Infrastructure (learn how to use types from a project without referencing it: http://blog.falafel.com/use-types-from-project-without-referencing/).
With this architecture in place, you can use dependency injection (http://deviq.com/dependency-injection/) to inject the desired implementation of a given type at runtime, which provides great flexibility and testability.
Setting up your solution with the proper dependencies between projects is critical to being successful with this approach, since a traditional UI -> Business Layer -> Data Layer setup will not allow you to invert dependencies. Once your solution is set up in this manner, you should follow the Explicit Dependencies Principle (http://deviq.com/explicit-dependencies-principle/) in all of your UI and service code.
Im starting a new application in WPF and I want it to have a good architecture so that it can be maintainable. Im using Entity Framework and what I planned so far is.
• View Layer: One project (startup) with the startup view, and main menus. Different projects for each type of view, for example, if I have views related with Books then I'd have a project named BooksView with all the views.
• Business Layer: One project for each type of Business Class, for example BusinessBooks. Each one would have a Repository with the specific operations and any helpers to do calculations if needed.
• Data Acess Layer: It contains a folder named Entity Framework with the DBContext and with the T4 generated classes and with a class named ContextCreator which has the following code:
public class ContextCreator : IDisposable
{
private MesaOperativaDB context;
public ContextCreator()
{
context = new MesaOperativaDB();
}
public MesaOperativaDB getContext()
{
return context;
}
public void Dispose()
{
context.Dispose();
}
}
Then a view would use the static repository of any project of the Business Layer that needs, and this repository would use the class above to get the DBContext and use it like this:
public static List<Novedades> GetNovedades()
{
using (ContextCreator db = new ContextCreator())
{
IQueryable<Novedades> novedades = db.getContext().Set<Novedades>().AsQueryable();
return novedades.ToList();
}
}
Is this approach any good?
Thank you in advance guys.
Though I am quite not sure of your application scale but it seems good to me that you have started on a right path for separation of concerns.
But you may need to rethink if creating separate project for each category of views does not introduce unnecessary complexity.
Again I am not sure if you are new to WPF, but for the View layer for better maintainability, loose coupling and hence testability etc., MVVM is the best chosen pattern to organize things in place.
For getting MVVM in place you may handcode everything from scratch or there are nice frameworks available like:
MVVM Lite
Assisticant
Also if you are planning towards a relatively big(layman term!!)/enterprise class application and since you are looking for highly maintainable, flexible application you may consider using PRISM framework from Microsoft. Prism Guidance and downloadable PDFs etc.
Once you finalized on the View part, the you need to focus on Validations for your app and whether you would be implementing validations in the ViewModel or in your domain objects. Assisticant framework has some good domain-centric validation mechanism built into it.
For the Data access layer, since you chose to go with EF, from my understanding so far, the Unit-Of-Work with Repository pattern would greatly help you to gain extensibility, testability etc. features.
If you are planning high on unit testability and loose coupling of your application, you need to consider Inversion of Control and Dependency Injection perhaps with a suitable framework.
Here you can check a WPF application framework to understand on how to organize different areas of a WPF application in a layered approach.
Hope this may help you to dig further.
I need to separate ViewModels in my MVC project from my business models (Data access layer) which lives in a separate library.
Assume that I have Database Access Layer classes in a separate library. Our primary project (MVC) does know nothing about those classes and they talk to each other through an Interface. It’s easy enough to use IOC and resolve dependency injection using Ninject or something, right?
Now DataAccessLayer contains class named Car with properties Engine and Wheel. In my MVC project (which doesn’t know nothing about DataAccessLayer and its classes) I need to use some Car objects. So I have another Car class (it’s just a pure ViewModel) and it has the same properties – Engine and Wheel (of course in real app there will be some differences between model and viewmodel, for the sake of simplicity let’s ignore that)
IDataAccessLayer Interface has a method called IEnumerable GetAllCars() that returns list of DataAccessLayer.Car objects.
Now I need to create MVCProject.Car collection, iterate through IEnumerable which was returned by GetAllCars(), on every iteration I need to create a new MVCProject.Car object, populate Engine and Wheel properties, and finally add that object to the Collection.
So: everytime I have to create almost the same structures and somehow manage them in different places.
Here is the problem, see? Or it isn’t? I feel like it will end up into big mess if I don’t change that. Don’t repeat yourself principle violation as it is. Tell me please how to make it right. Using I don’t know proxies or prototypes or maybe some other design pattern which I suck anyway. Or some sort of a tool like Ninject (which I only know how to use as IOC container) or Automapper or whatever, which I probably will suck even more than I suck in design patterns.
I also don't see much of a reason to keep the DAL separate from the MVC layer. In case you're interested, here is the layout that I've used for multiple project and I find it is very usable and flexible.
DataObjects
Basic objects with only properties. Also includes enumerations which the DataObjects use.
DataAccess
Inherit from DataObjects and add GetByPrimaryKey, GetByForeignKey, GetByUniqueIndex, GetAll, etc., etc. Also contains the Caching layer where you would find StateCache, CountryCache, etc. for quick access to frequently used things. The "GetBy" methods will utilize the caching layer whenever possible.
Logic
Static classes, one for each DataObject\Access type. Includes logical work other than simple fetches as detailed in the DataAccess layer.
Web\Front-end
UI works with DataAccess and Logic layers to get and update objects as well as call other defined logical APIs.
I use my own custom-made code generator to generate 98% of this code (except the UI layer).
It sounds like your MVC library should know about your data-access library, shouldn't it?
Or, if you really want to keep your MVC and DAL libraries separate, you could always add a third library with references to both MVC and DAL. Then it could handle retrieving cars from the one library, and converting them to the other.
But again, I don't see why your controllers (or ViewModel, from what you've described) shouldn't have access to the DAL. Your car ViewModel would retrieve instances of Cars from the DAL, and go from there. So long as the way in which it receives the cars is coded through an interface, you should be able to stub that out later for your unit tests.
EDIT
So it looks like you think you'll be changing the entire DAL around later, and you want to minimize the difficulty of that? If that's the case, you might look at the adapter pattern. You would pass all your DAL objects to adapters, which would return to you objects in your business layer. Then, if your DAL changes, you just update your adapters.
I found a way to make it really ugly :)
The Goal: Caller doesn't know nothing about Model Entities at DataAccessLayer, and gets all the data through the interface.
How to get the data without manual mapping between Model and Viewmodel?
Through reflection.
public IEnumerable<T> GetCars<T>()
{
var lst = new List<T>();
_data.GetTable<Cars>().ToList().ForEach(x =>
{
var newCar = Activator.CreateInstance<T>();
typeof(T).GetProperty("Engine").SetValue(newCar, x.Engine, null);
typeof(T).GetProperty("Wheel").SetValue(newCar, x.Wheel, null);
lst.Add(newCar);
});
return lst;
}
It Works. But the biggest question here is it fair and considerable architectural decision? How the performance will be affected in a real life app?