Using this sample project as a guideline, I am setting up a new project. My project will follow the same basic architecture, only in addition to an mvc project, I will also have a wcf web service project(or possibly servicestack.net)
Instead of using Unity for DI as in the sample, I am using Ninject. Currently I am configuring Ninject as follows to only instantiate one instance of Database factory per web request(and thus one datacontext class per request (using EF 4.1 code first btw))
kernel.Bind<IDatabaseFactory>()
.To<DatabaseFactory>()
.InScope(ctx => HttpContext.Current);
I am curious if this method is sufficient? Or would it be better to let the factory class handle the instantiation of datacontext per http request(and possibly per thread if I were design for non web based front-ends in the future)? If so, are there any examples out there of how to go about this?
Or is there a completely better solution to handle this?
You should use .InRequestScope() instead of .InScope(ctx => HttpContext.Current). It ensures that the appropriate scope is used depending on whether the instance is requested via WCF or via ASP.NET MVC. Unfortunately to take full advantage of this you'll have to use the current continous integration builds from http://teamcity.codebetter.com . See also
https://github.com/ninject/ninject.extensions.wcf
https://github.com/ninject/ninject.web.mvc
Related
I'm working on my first Blazor Server project and I am slowly fixing a lot of initial design errors that I made when I started out. I've been using C# for a while, but I'm new to web development, new to ASP.Net, new to Blazor, and new to web architecture standards, hence why I made so many mistakes early on when I didn't have a strong understanding of how best to implement my project in a way that promotes clean code and long term maintainability.
I've recently restructured my solution so that it follows the "Clean Architecture" outlined in this Microsoft documentation. I now have the following projects, which aim to mirror those described in the document:
CoreWebApp: A Blazor project, pages and components live here.
Core: A Class Library project, the domain model, interfaces, business logic, etc, live here.
Infrastructure: Anything to do with having EF Core access the underlying database lives here, ie ApplicationDbContext, any implementations of Repositories, etc.
I am at a point where I want to move existing implementations of the repository pattern into the Infrastructure project. This will allow me to decouple the Core project from the Infrastructure project by utilising the Dependency Injection system so that any business logic that uses the repositories depends only on the interfaces to those repositories (as defined in Core) and not the actual implementations themselves (to be defined in Infrastructure).
Both the Microsoft documentation linked above, and this video by CodeWrinkles on YouTube make the following two suggestions on how to correctly use DbContext in a Blazor Server project (I'll talk specifically about using DbContext in the context of a repository):
Scope usage of a repository to each individual database request. Basically every time you need the repository you instantiate a new instance, do what needs to be done, and as soon as the use of the repo goes out of scope it is automatically disposed. This is the shortest lived scope for the underlying DbContext and helps to prevent concurrency issues, but also forgoes the benefits of change tracking.
Scope the usage of a repository to the lifecycle of a component. Basically you create an instance of a repository in OnInitialisedAsync, and destroy the repository in the Dispose() method of the component. This allows usage of EF Cores change tracking.
The problem with these two approaches is that they don't allow for use of the DI system, in both cases the repository must be new'd and thus the coupling between Core and Infrastructure remains unbroken.
The one thing that I can't seem to understand is why case 2 can't be achieved by declaring the repository as a Transient service in Program.cs. (I suppose case 1 could also be achieved, you'd just hide spinning up a new DbContext on every access to the repository within the methods it exposes). In both the Microsoft documentation and the CodeWrinkles video they seem to lean pretty heavily on this wording for why the Transient scope isn't well aligned with DbContext:
Transient results in a new instance per request; but as components can be long-lived, this results in a longer-lived context than may be intended.
It seems counterintuitive to make this statement, and then provide a solution to the DbContext lifetime problem that will enable a lifetime that will align with the stated problem.
Scoping a repository to the lifetime of a component seems, to me, to be exactly the same as injecting a Transient instance of a repository as a service. When the component is created a new instance of the service is created, when the user navigates away from the page this instance is destroyed. If the user comes back to the page another instance is created and it will be different to the previous instance due to the nature of Transient services.
What I'd like to know is if there is any reason why I shouldn't create my repositories as Transient services? Is there some deeper aspect to the problem that I've missed? Or is the information that has been provided trying to lead me into not being able to take advantage of the DI system for no apparent reason? Any discussion on this is greatly appreciated!
It's a complex issue. With no silver bullet solution. Basically, you can't have you cake and eat it.
You either use EF as an [ORM] Object Request Mapper or you let EF manage your complex objects and in the process surrender your "Clean Design" architecture.
In a Clean Design solution, you map data classes to tables or views. Each transaction uses a "unit of work" Db Context obtained from a DBContextFactory. You only enable tracking on Create/Update/Delete transactions.
An order is a good example.
A Clean Design solution has data classes for the order and order items. A composite order object in the Core domain is built by make two queries into the data pipeline. One item query to get the order and one list query to get the order items associated with that order.
EF lets you build a data class which includes both the order data and a list of order items. You can open that data class in a DbContext, "process" that order by making changes and then call "SaveAsync" to save it back to the database. EF does all the complex stuff in building the queries and tracking the changes. It also holds the DbContext open for a long period.
Using EF to manage your complex objects closely couples your application domain with your infrastructure domain. Your application is welded to EF and the data stores it supports. It's why you will see some authors asserting that implementing the Repository Pattern with EF is an anti-pattern.
Taking the Order example above, you normally use a Scoped DI View Service to hold and manage the Order data. Your Order Form (Component) injects the service, calls an async get method to populate the service with the current data and displays it. You will almost certainly only ever have one Order open in an SPA. The data lives in the view service not the UI front end.
You can use transient services, but you must ensure they:
Don't use DBContexts
Don't implement IDisposable
Why? The DI container retains a reference to any Transient service it creates that implements IDisposable - it needs to make sure the service is disposed. However, it only disposes that service when the container itself is disposed. You build up redundant instances until the SPA closes down.
There are some situations where the Scoped service is too broad, but the Transient option isn't applicable such as a service that implements IDisposable. Using OwningComponentBase can help you solve that problem, but it can introduce a new set of problems.
If you want to see a working Clean Design Repository pattern example there's an article here - https://www.codeproject.com/Articles/5350000/A-Different-Repository-Pattern-Implementation - with a repo.
On startup of our asp net core applications we read a whole bunch of configuration from our appsettings.json and map it to a concrete type that we inject in our service layer.
Consider the two examples below :
A : services.AddSingleton(Configuration.GetSection("Auth0").Get<Auth0Settings>());
B : services.Configure<Auth0Settings>(Configuration);
I know using option A I can simply inject the concrete type into my constructor and use it whereas with option B I am required to use the Options Pattern
Im unsure what benefits option B provides over option A and why I would use it.
In the end both approaches give the same result and you cann access an instance of Auth0Settings via DI in e.g. your controllers.
For me there are two arguments in favor of the Options-Pattern.
Expressivness - you make a clear destinction about application logic
(services) and configuration (options). This make your code better
to read and your intent easer to understand.
Flexibility - the Options-Pattern provides additional features (like
validation and post-processing)
Although you might not need the additional features the first argument is still on the plate.
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.
app.CreatePerOwinContext(DataContext.Create);
I have the above line to create a data context this code came with project when i kick a new MVC 5 project. At the same time, i am using autofac to inject single instance per request in my dependency registrar.
builder.RegisterType<DataContext>().As<IDbContext>().InstancePerRequest();
What is the best way to use owin and DI container?
I have a DataContext class which has a static Method called Create as above and this break when I try to inject a logger in a database class for example.
I am also interested in a sample project if any , demonstrating DI and owin in the same project.
It is not necessary to use both OWIN and a DI container. I can understand your confusion, since the documentation on CreatePerOwinContext is very sparse, but the truth is that this feature is only implemented as a "poor man's DI", and should probably be replaced by a normal DI framework. Microsoft's Hao Kung, who is on the ASP.NET team says you are free to replace it with a proper DI framework.
If you're not fetching the instance created by the OWIN middleware, and instead injecting your context into your controllers, then you can safely remove it. Just remember to update the scaffolded controllers accordingly.
I'm in the process of trying out a few things with MVC whilst designing a system and wanted to try and see if I could use the concept of Controllers outside of the MVC framework. When I say outside, I mean within my own C# service as opposed to a web-site.
I started a simple console application to test the theory and it was simple enough to change the profile to a non-client profile, add in System.Web.Mvc, create a controller and have it return a JsonResult. The ease of which this got set up pleased me as that is half the work done if I want a service to respond with JSON.
The next step is to set up a Http Server class, and I would love it if I could leverage the other part of the framework which will map incoming requests to my controllers. Unfortunately, this is the part where I am lost and I have no idea what code goes on behind to arrive at a particular controller's function with the parameters all in place.
Has anyone got an idea on how to accomplish this, or a resource to look at?
In short: I'd like to leverage the use of Controllers in my own service, running it's own HTTP Server.
You can use the design pattern without using the framework - what I mean is, you can apply the model view controller pattern wherever you believe it solves the problem - if you think that you can replace "view" with "service", you could apply some of the concepts...
http://msdn.microsoft.com/en-us/library/ff649643.aspx
However, there are other patterns that may lend themselves better to services, although if we are talking specifically about a JSON service, then just using the ASP.NET MVC framework as it is would work well (rather than trying to re-write it).
Are you not trying to reinvent the wheel?
If returning JSON is one of your main purpose then WCF fulfills your need. Having WCF with you you are free to host it in IIS. This serves your second purpose having its own HTTP server.
You are trying to achieve some kind of routing where based on URL your different actions will be called. Isn't it similar to having a WCF service with different methods and client is calling each of them with different URL?
Trying controller concept in a non web application seems to be innovative, however in your case it looks like over-engineering.
The basic MVC pattern isn't all the difficult to replicate. I would seriously consider writing your own, rather than trying to shoehorn the MVC classes into your app.
Simon
If it helps you, the entire ASP.Net MVC Framework is open source, you can download it all from http://aspnet.codeplex.com/ . You can use the libraries here to view how the Framework is doing things behind the scenes and adapt things for your own use as appropriate.