ASP.NET MVC with composition pattern - c#

I need my controllers to have several functionalities, e.g.,
Some of the controllers save my entities to a database, so I use the Repository pattern here (passing the Repository in the constructor).
Some of the controllers, on the other hand, do this PLUS sending my entities to an external service. In this case I pass the service client in the constructor of the Controller too.
Since my controller cannot inherit from two classes, e.g.,
DbEntityController: The one that deals with a database repository.
ServiceEntityController: The one that deals with a remote service client.
Can you give me a couple of advises about how to implement a sort of composition pattern for MVC Controllers? I am actually concerned about the URL routing etc. Is this going to work if my action methods delegate their tasks to an "inner" controller.
Any ideas will help a lot!
UPDATE:
These are my constructors more or less (I use DI with Unity by the way)
DbEntityController(IDbRepository<TEntity>)
ServiceEntityController(IServiceRepository<TEntity>)
OrderController(IDbRepository<IOrder>, IServiceRepository<IOrder>)
AddressController(IDbRepository<IAddress>)
Somehow OrderController inherits from both DbEntityController and ServiceEntityController.

Related

SimpleInjector: End-to-end testing of controller's methods on a test database

I have a web app with several REST API controllers. This controllers got injected repositories as per this tutorial using SimpleInjector. I'd like to add some end-to-end testing to my project to make sure controller's method calls affect database in predictable manner (I'm using EF6, MySQL, code first). I was going to use this plan to test my app. I like overall approach but it seems like in this approach author is feeding db context directly into controller. In my case I have a Controller that gets an injected Repository from constructor and in turn Repositiry gets injected DbContext. Obviously I can hardcode the chain of creating DbContext, instantiating Repository followed by instantiating a Controller but it kinda defies the purpose of using the SimpleInjector, isn't it? I think there should be the way do it in more transparrent manner.
Basically I would like to inject separate database into my tests. When server is running it's using one database, when tests are running they are using the other ad-hoc database.
I have my test classes in a separate project, so I will need a way to instantiate my Controllers and Repositories from the main project. I'm not sure how I can do it either. Is it a good idea to expose my SimpleInjector.Container from another project somehow?
Additional info: I'm using .Net Framework (non-Core), I would like to manage withouth mocking for now unless it's required.
You can abstract the DbContext behind an interface and use SimpleInjector's option to override registrations for your tests. That will allow you to register a different implementation of your context for testing. Then in your test setup code call your standarad registrations, assuming they're all in your composition root and/or bootstrapping projedct. Then flip the override switch and register the test context.
Override Registrations
- For testing only
In your case, I would expect you to don't have to do anything in particular. Your end-to-end tests would call into a test version of the web application over HTTP, and this test application is configured with a connection string that points at a test database. This way you can use the exact same DI configuration, without having to do any changes. You certainly don't want to inject a different DbContext during testing.
Another option is to test in-memory, which means you don't call the web application over HTTP, but instead request a controller directly from Simple Injector and call its methods. Here the same holds: the only thing you want to change is your connection string, which is something that should already be configurable.

ActionResult from non-controller classes

I have decided that my controllers are getting a little to cluttered, and decided to adopt a pipeline-style system as I have used in a WebAPI project. The pipeline consists of actions, that get more and more general, i.e: ViewAccountDetailsAction > AccountAction > AuthenticatedAction > EmptyAction. The Actions both add to the pipleline in order of inheritance, and expose members, or abstract methods for different scenarios.
My problem lies in how to return views from pipeline elements. In the WebAPI example, it was as easy as returning an IHttpActionResult which didn't have to perform any view rendering, however, MVC is required to render its responses differently, with the additional step of Razor.
As Controllers expose internal protected helper methods like View() or RedirectToAction, I cant use these outside the controllers themselves.
Is there an elegant way to render these out? I have seen a few ways to do this, each being either cumbersome, or giving me uncomfortable feelings.
My most favoured way at the moment is to make an internal base class hiding the protected methods, and making them internal, whilst calling the base methods. The controller instance will then be provided to the instantiated action. Is there anything overly wrong with this? I can't think of any abusable cases, but wanted to see if there was any community consensus on the matter.
I would recommend taking your approach a step further.
This took a little bit of research, but I based it on an approach I did for a client with Web API 2. Basically the idea was we created a custom ControllerSelector, ActionSelector and ActionDescriptors and a controller base class that exposed a strongly typed business layer. Then through reflection/custom attributes, we marshalled the call to the business layer, handling transformations to an HttpResponseResponse message generically, including errors.
Controller: http://pastebin.com/iK8ieBKD
ControllerSelector: http://pastebin.com/qvEbggrP
ActionSelector: http://pastebin.com/CEFNeKZZ
The first thing you'll need to do is look at:
http://www.dotnet-tricks.com/Tutorial/mvc/LYHK270114-Detailed-ASP.NET-MVC-Pipeline.html
Unfortunately ASP.NET MVC5's pipeline is much less flexible than Web API 2's. However you can do three things:
Custom Controller Factory: https://msdn.microsoft.com/en-us/library/system.web.mvc.icontrollerfactory(v=vs.118).aspx
Custom ControllerDescriptor
Custom ActionInvoker that interprets the ControllerDescriptor: https://msdn.microsoft.com/en-us/library/system.web.mvc.iactioninvoker(v=vs.118).aspx
This way you leave your controller to do what controllers do best, and create a contract for your controller to generically interpret using your new pipeline. This is really the right way to do it.
High jacking/bastardizing the controller as you suggested I don't think is a great plan, this is a much more robust solution, however it would take significant effort. Best of luck!

Right way to work with dbContext

Summary
This question is for a methodology. The answer should be a link to the holy grail in working with contexts for the described scenario.
We have been experiencing different problems in our MVC web application project, related to the use of dbContext.
After reading many question-answer blogs, articles ... including proposals with repositories and injection patterns, Owin, Entity Framework, Ninject, we are still not clear about the right way to work with dbContext’s.
Is there any article, demo, with “The Way” to do it in a more complex application than just “CRUD” operations using separation between MVVC-presentation / Domain Entities / Logic / DataAccess layers, including Identity security handling users and roles permissions?
Description
Previously, our approach was to create dbContext objects when needed in each repository.
Soon we discovered errors like “dbContext is disposed” since the connection dies together with the repository function. This makes the retrieved objects “partially available” to the upper layers in the app (using the trick .ToList(), limited because we can access collections and attributes but not later navigation into the object child tables, and so on). Also using 2 contexts from different repositories, we got an exception telling that 2 contexts are trying to register changes to the same object.
Due to timed commitments to deliver prototypes, we created a single static dbContext shared for the whole application, which is called from everywhere when needed (Controllers, Models, Logic, DataAccess, database initializers). We are aware that is a very dirty workaround but it has been working better than the previous approach.
Still with problems: dbContext can handle only 1 async method call at a time, and we can have many calls (eg. userManager.FindByNameAsync - there are only async methods). Exception: “A second operation started on this context before a previous asynchronous operation completed”.
We were thinking about creating the context as the very first step when an action is called in the controller, then to carry this object as “relay race” to every other layer or function called. In this way the connection will live from the “click in the browser” until the response is loaded back on it. But we don’t like the idea that every single function must have an extra parameter “context” just to share the connection through the layers for the entire operation route.
We are sure that we are not the first ones wondering about what is the right way to use contexts.
Application layers
We have these (logical) layers, differents workspaces, but same webapp MVC project, top to down:
Views: HTML + Razor + JQuery + CSS. Code here is restricted to the layout, but some HTML might depend on the Role. Method calls are to controllers only, plus utils (like formatting).
ViewModels: The data container to be exchanged between Controllers and Views. Classes only define attributes, plus functions to convert to and from Domain entities only (Translators).
Controllers: Actions called from the browser result in calls to functions in the Logic layers. Authentication here restricts access to actions or limits inside an action. Controllers avoid using Domain entities but ViewModels, so that to communicate with Logic layer ViewModels translation functions are called.
Domain Entities: Used for the logic layer, and used to create database tables by Entity Framework.
Logic Classes: A Domain entity has an EntityLogic class with all the operations. These are the core where all the rules that are common and abstracted from specific consumer clients (ViewModels are unknown).
Repositories: To access the database. Not sure if we do need this since Domain entities are already mapped to objects in database by Entity Framework.
Typical scenario
The browser calls an action (POST) in the Products controller to edit a product. The ProductViewModel is used as container of the data.
The controller action is restricted to a collection of roles. Inside the action, depending of the role, a different Logic function is called and ProductViewModel is translated to ProductDomainEntity and passed as parameter.
The logic EditProduct function calls others functions in different logic classes and also use localization and security to restrict or filter. The logic may or may not call a Repository to access the data, or to use a global context for all, and deliver the resulting domain entity collections to the Logic.
Based on the results, the logic may or may not try to navigate the results’ children collections. The results are given back to the controller action as domain entity (or collection of), and depending of this results, the controller may call more Logic, or redirect to another action or respond with a View translating the results to the right ViewModel.
Where, when and how to create the dbContext to support the whole operation in the best way?
UPDATE: All classes within the Logic layer are static. The methods are called from controllers simply like this:
UserLogic.GetCompanyUserRoles(user)
, or
user.GetCompanyRoles()
where GetCompanyRoles() is an extension method for User implemented in UserLogic. Thus, no instances for Logic classes means no constructors to receive a dbContext to use inside its methods.
I want a static method inside a static class to know where to get the instance of the dbContext active to the current HttpRequest.
Could NInject and OnePerRequestHttpModule help with this? Someone who tried?
I don't believe there is a "Holy Grail" or magic-bullet answer to this or any other problem with EF / DbContexts. Because of that, I also don't believe that there is one definitive answer to your question, and that any answers will be primarily opinion-based. However I have found personally that using a CQRS pattern rather than a repository pattern allows for more control and fewer problems when dealing with EF semantics and quirks. Here are a few links that you may (or may not) find helpful:
https://stackoverflow.com/a/21352268/304832
https://stackoverflow.com/a/21584605/304832
https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91
https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92
http://github.com/danludwig/tripod
Some more direct answers:
...This makes the retrieved objects “partially available” to the upper layers in the app (using the trick .ToList(), limited because we can access collections and attributes but not later navigation into the object child tables, and so on). Also using 2 contexts from different repositories, we got an exception telling that 2 contexts are trying to register changes to the same object.
The solutions to these problems are to 1) eager load all of the child and navigation properties that you will need when initially executing the query instead of lazy loading, and 2) only work with 1 DbContext instance per HTTP request (inversion of control containers can help with this).
Due to timed commitments to deliver prototypes, we created a single static dbContext shared for the whole application, which is called from everywhere when needed (Controllers, Models, Logic, DataAccess, database initializers). We are aware that is a very dirty workaround but it has been working better than the previous approach.
This is actually much worse than a "dirty workaround", as you will start to see very strange and hard to debug errors when you have a static DbContext instance. I am very surprised to hear that this is working better than your previous approach, but it only points out that there are more problems with your previous approach if this one works better.
We were thinking about creating the context as the very first step when an action is called in the controller, then to carry this object as “relay race” to every other layer or function called. In this way the connection will live from the “click in the browser” until the response is loaded back on it. But we don’t like the idea that every single function must have an extra parameter “context” just to share the connection through the layers for the entire operation route
This is what an Inversion of Control container can do for you, so that you don't have to keep passing around instances. If you register your DbContext instance one per HTTP request, you can use the container (and constructor injection) to get at that instance without having to pass it around in method arguments (or worse).
ViewModels: The data container to be exchanged between Controllers and Views. Classes only define attributes, plus functions to convert to and from Domain entities only (Translators).
Little piece of advice: Don't declare functions like this on your ViewModels. ViewModels should be dumb data containers, void of behavior, even translation behavior. Do the translation in your controllers, or in another layer (like a Query layer). ViewModels can have functions to expose derived data properties that are based on other data properties, but without behavior.
Logic Classes: A Domain entity has an EntityLogic class with all the operations. These are the core where all the rules that are common and abstracted from specific consumer clients (ViewModels are unknown).
This could be the fault in your current design. Boiling all of your business rule and logic into entity-specific classes can get messy, especially when dealing with repositories. What about business rules and logic that span entities or even aggregates? Which entity logic class would they belong to?
A CQRS approach pushes you out of this mode of thinking about rules and logic, and more into a paradigm of thinking about use cases. Each "browser click" is probably going to boil down to some use case that the user wants to invoke or consume. You can find out what the parameters of that use case are (for example, which child / navigation data to eager load) and then write 1 (one) query handler or command handler to wrap the entire use case. When you find common subroutines that are part of more than one query or command, you can factor those out into extension methods, internal methods, or even other command and query handlers.
If you are looking for a good place to start, I think that you will get the most bang for your buck by first learning how to properly use a good Inversion of Control container (like Ninject or SimpleInjector) to register your EF DbContext so that only 1 instance gets created for each HTTP request. This should help you avoid your disposal and multi-context exceptions at the very least.
I always use a BaseController that contains a dbContext and passes it to the logic functions (Extensions i call). That way you only use one context per call and if something fails it will do a rollback.
Example:
Controller1 that inherits BaseController
Controller1 now have access to the property db that is a context
Controller1 contains an action "Action1"
Action1 will call the function "LogicFunctionX(db, value1, Membership.CurrentUserId, true)"
In Action1 you can call other logic functions or even call them inside "LogicFunctionX". Always passing the property db through functions.
To save the context i do it inside the controller (mostly) after calling all the logic functions.
Note: the argument true that i pass in LogicFunctionX is to save the context inside or not. Like:
if(Save)
db.SaveChanges();
I had several problems before doing this.

3 Tier Architecture with NHibernate, Ninject and Windows Forms

So I'm in the middle of rafactoring a small to medium sized Windows Forms application backed by a SQLite database accessed through NHibernate. The current solution contains only an App Project and Lib Project so it is not very well structured and tightly coupled in many places.
I started off with a structure like in this answer but ran into some problems down the road.
DB initialization:
Since the code building the NHibernate SessionFactory is in the DAL and I need to inject an ISession into my repositories, I need to reference the DAL and NHibernate in my Forms project directly to be able to set up the DI with Ninject (which should be done in the App Project / Presentation Layer right?)
Isn't that one of the things I try to avoid with such an architecture?
In an ideal world which projects should reference eachother?
DI in general:
I have a decently hard time figuring out how to do DI properly. I read about using a composition root to only have one place where the Ninject container is directly used but that doesn't really play well with the current way NHibernate Sessions are used.
We have a MainForm which is obviously the applications entry point and keeps one Session during its whole lifetime. In addition the user can open multiple SubForms (mostly but not exclusively) for editing single entities) which currently each have a separate Session with a shorter lifetime. This is accomplished with a static Helper exposing the SessionFactory and opening new Sessions as required.
Is there another way of using DI with Windows Forms besides the composition root pattern?
How can I make use of Ninjects capabilites to do scoped injection to manage my NHibernate Sessions on a per-form basis (if possible at all)?
Terminology:
I got a little confused as to what is a Repository versus a Service. One comment on the posted answer states "it is ok for the repository to contain business-logic, you can just call it a service in this case". It felt a little useless with our repositories only containing basic CRUD operations when we often wanted to push filtering etc. into the database. So we went ahead and extended the repositories with methods like GetByName or more complex GetAssignmentCandidates. It felt appropiate since the implementations are in the Business Layer but they are still called repositories. Also we went with Controllers for classes interacting directly with UI elements but I think that name is more common in the Web world.
Should our Repositories actually be called Services?
Sorry for the wall of text. Any answers would be greatly appreciated!
Regarding 1:
Yes and no. Yes you would prefer the UI Layer not to be dependent on some specifics of x-layers down. But it isn't. The composition root is just residing in the same assembly, logically it's not the same layer.
Regarding 2:
Limit the usage of the container. Factories (for Sessions,..) are sometimes necessary. Using static should be avoided. Some Frameworks however prevent you from using the ideal design. In that case try to approximate as much as possible.
If you can currently do new FooForm() then you can replace this by DI or a DI Factory (p.Ex. ninject.extensions.Factory). If you have absolutely no control on how a type is instanciated then you'll need to use static to access the kernel like a service locator and then "locate" direct dependencies (while indirect dependencies are injected into direct dependencies by the DI container).
Regarding 3: i think this is somewhat controversial and probably often missunderstood. I don't think it's really that important what you call your classes (of course it is, but consistency across your code base is more important than deciding whether to name them all Repository or Service), what's important is how you design their responsibilities and relationships.
As such i myself prefer to extract filters and stuff in the -Query named classes, each providing exactly one method. But others have other preferences... i think there's been enough blog posts etc. on this topic that there's no use in rehashing this here.
Best practice to implement for situation like yours is to use MVP design pattern. Here its the architecture that i can offer to you.
MyApp.Infrastructure // Base Layer - No reference
MyApp.Models // Domain Layer - Reference to Infrastructure
MyApp.Presenter // Acts like controllers in MVC - Reference to Service, Models,
MyApp.Repository.NH // DAL layer - Reference to Models, Infrastructure
MyApp.Services // BLL Layer - Reference to Repository, Models
MyApp.Services.Cache // Cached BLL Layer(Extremely recommended) - Reference to Services, Models
MyApp.UI.Web.WebForms // UI Layer - Reference to all of layers
I will try to do my best to explain with the example of basic implementation of 'Category' model.
-Infrastructure-
EntityBase.cs
BussinesRule.cs
IEntity.cs
IRepository.cs
-Models-
Categories(Folder)
Category.cs // Implements IEntity and derives from EntityBase
ICategoryRepository.cs // Implements IRepository
-Presenter-
Interfaces
IHomeView.cs // Put every property and methods you need.
ICategoryPresenter.cs
Implementations
CategoryPresenter.cs // Implements ICategoryPresenter
CategoryPresenter(IHomeView view, ICategorySevice categorySevice){
}
-Repository-
Repositories(Folder)
GenricRepository.cs // Implements IRepository
CategoryRepository : Implements ICategoryRepository and derives from GenricRepository
-Services-
Interfaces
ICategorySevice.cs
AddCategory(Category model);
Implementations
CategorySevice.cs // Implements ICategorySevice
CategorySevice(ICategoryRepository categoryRepository ){}
AddCategory(Category model){
// Do staff by ICategoryRepository implementation.
}
-Services.Cache-
// It all depents of your choose.. Radis or Web cache..
-UI.Web.WebForms-
Views - Home(Folder) // Implement a structure like in MVC views.
Index.aspx // Implements IHomeView
Page_Init(){
// Get instance of Presenter
var categoryPresenter = CategoryPresenter(this, new CategorySevice);
}
I'm not sure if i got your question correct, but maybe give you an idea:)

Injecting a service into another service

I have an MVC project which has two services an OrganisationService and an AgreementService, my problem is that some of the organisations belong to a group/parent structure, when this is the case I need to get all agreements that belong to any of the organisations within the group.
I already have a method in my OrganisationService that can return a list of all the ids for organisations within the structure:
IEnumerable<int> GetRelatedOrganisationIds(int id)
I could create a method in the AgreementService which accepts the result of this but then I would need to inject both services into my controller and call them in turn e.g.
GetAgreementsByOrganisationIdList(IEnumerable<int> organisationIdList)
Is it ok to inject the OrganisationService into the AgreementService so that it can do the work itself? For example the following method would call GetRelatedOrganisationIds internally:
GetAgreementsByOrganisationId(int id)
Another reason I would like to inject it into the AgreementService is that I would not need to remember to check if the organisation was in a group/parent relationship and look up the ids each time I wanted to get a list of agreements.
I also thought of creating an OrganisationGroupParentInformationProvider and injecting that into the AgreementService instead, I may have spent far too much time thinking about this one.... how would you do it?
Yes, it would be fine to inject one service into the constructor of another. However, you might want to consider creating an interface for OrganisationService and having your AgreementService depend upon that abstraction, instead.
Another approach would be to create a new service with dependencies on both AgreementService and OrganisationService, and have that new service carry out the responsibility. The new service would of course be injected into your controller.
For guidance, consider whether having it all under AgreementService would violate the Single Responsibility Principle and/or Interface Segregation Principle. If so, make a new service.
Is it ok to inject the OrganisationService into the AgreementService so that it can do the work itself?
That wouldn't be injecting it. That would be making it a dependency to it. Regardless, I would say the way you have it is a better architecture because it's more testable. By having the agreement service call the organizations service on its own it's certainly less testable because somewhere you're going to have to inject an instance of the organization service.

Categories