In my app, I create a dbcontext for every call and dependency inject it through Ninject.
I've been thinking of creating a singleton class (ContextManager - BaseController would set the context on every request) to make the context available from everywhere, thus allowing all the services to share the same context. This would furthermore make it easy to, for example, disable proxy creating etc. seeing as the context is managed from one place only.
However, seeing as the object is a singleton object the context would be overwritten per each request which won't work for me (I don't want multiple requests sharing a single context).
What would be the best way to do this (how to preferably a single context ONLY in request scope)?
What you're describing is not a Singleton, but a Request-Scoped object. ASP.NET MVC has strong support for dependency injection, and you should allow your DI bindings to determine where the context comes from, rather than instantiating it yourself. Ninject has binding syntax to support this. I think it goes:
Bind<DataContext>().ToSelf().InRequestScope();
As long as you are using good Dependency-Injection patterns consistently, this should cause the same DataContext instance to be passed to every dependency you have within the same request.
The advantage to relying on Dependency Injection for construction of your context is that if you want to change details like disabling change tracking on the context, you can simply change your DI binding to use a custom method or factory, and the rest of your code doesn't have to change at all.
Singleton is not the right approach here, but this is not too hard to implement, by simply instantiating your data context in your controller and injecting it into your service classes, e.g.:
public class SomeController {
private DataContext _context;
private SomeService _service;
public SomeController() {
_context = ...InstantiateContext();
_service = new SomeService(_context);
}
}
This also allows makes it relatively simple to inject your context into your controller if you wish to unit test that. You can also relatively simply dispose of your context by coding this into the dispose method of the controller class (as noted above, a base controller class may be useful).
A singleton carries some persistent state - this is anathema to unit testing and will ultimately give you difficulties in your code.
Related
I am using SoapCore to create a web service for my ASP.NET Core MVC application.
I am using Entity Framework Core and a simple Repository pattern to get my DB data.
I am injecting my repository classes via .AddSingleton() in my Startup.cs:
services.AddSingleton<IImportRepository, ImportRepository>();
services.AddSingleton<IWebService, WebService>();
Since the EF DbContext is scoped I get an error when calling my web service:
Cannot consume scoped service 'App.Data.ApplicationDbContext' from
singleton 'App._Repository.IImportRepository'.
When I use .AddScoped() instead, it works fine.
I've read injecting scoped dependencies via a controllers/classes constructor is bad practice, since it "falls back" to be a singleton or behaves like one.
I wonder if there is another way to make it work with singletons or if this has some major draw backs in the long term (about 100-200 users will use the site) when using scoped injections in my controllers via the ctor?
Simply put, your go-to lifetime should be "scoped". You should only use a singleton or transient lifetime if you have a good reason to do so. For a singleton, that's stuff like managing locks or holding data that needs to persist for the lifetime of the application, neither of which applies to the concept of a repository. Repositories should be entirely disposable. The point is to persist to the database or to some other store, so they should not contain any data in their own right that needs to be persisted.
Long and short, your best bet here is to simply make your repo(s) scoped, so you can directly inject the context. As far as constructor injection goes, I'm not sure where you got the idea that that's a bad practice. It's in fact how dependency injection works in most cases, so you can't really have one without the other.
If you absolutely need to have a singleton, then your only option is the service locator antipattern. For that, you will inject IServiceProvider:
public class MyRepo
{
private readonly IServiceProvider _serviceProvider;
public MyRepo(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
...
}
Then, each time you need the context (that's important), you'll need to do:
using (var scope = _serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyContext>();
// do something with context
}
Scoped objects cannot be injected in to singleton objects. Its simple as this, singletons are created only once when the app is starting and used by all the subsequent requests. Scoped objected are created during each request and disposed at the end of the request. So there is no way for the previously created single object to know about the scoped objects creating during each request. So using scoped objects is not possible in singletons. But the the other way around is possible.
injecting scoped dependencies via a controllers/classes constructor
I don't think its a bad practice at all. If not how are you planing to do unit testing?
Also its not right to make DB context singleton. You will face cashing issues/data anomalies in parallel and subsequent requests. In my opinion DB context has to be scoped and all the objects that uses the db-context has to be scoped all the way up.
So in you case, make all the objects ImportRepository, WebService and DB Context all scoped.
Cheers,
Maybe this question has some explanation around but could not find the best solution to this:
I was reading this blog post from Mark Seemann about the captive dependencies and as far as I understand at the end of the post he comes to conclusion never use or at least try to avoid the captive dependencies otherwise there will be troubles (so far is OK). Here is another post from Autofac documentation.
They suggest using captive dependencies only by purpose (when you know what you are doing!). This made me think about a situation I have on my website. I have like 10 services, all of them rely on DbContext for database operations. I think they could easily be registered as InstancePerLifetimeScope if I fix the problem for DbContext not to hold it forever in memory attached to my services. (I am using Autofac in my case). So, I thought a good starting point would be to create all of these as per lifetime instances and the DbContext as instance per request. Then in my services, I would use something like that:
public class MyService
{
private readonly IDbContext _dbContext = DependencyResolver.Current.GetService<IDbContext>();
private MyModel GetMyModel() => Mapper.Map<MyModel>(_dbContext.MyTable.FirstOrDefault());
}
And then in my startup class I have:
builder.RegisterType<ApplicationDbContext>().As<IDbContext>().InstancePerRequest();
builder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
Does this pattern work correctly, I mean not keeping the dbContext forever attached to any service, so it will be disposed at the end of the request and if it works, is there any performance issue from this line:
private readonly IDbContext _dbContext = DependencyResolver.Current.GetService<IDbContext>();
compared to constructor injection(There are many invocations from dbContext to database so I am afraid to get IDbContext every time I want to use it because it might be resource consuming) ?
The reason I want dbContext to be instance per request and not instance per dependency is that I have implemented the unit of work pattern on top of the dbContext object.
A normal method in my controller would look like:
public ActionResult DoSth()
{
using(var unitOfWork = UnitOfWorkManager.NewUnitOfWork())
{
//do stuff
try
{
unitOfWork.Commit();
return View();
}
catch(Exception e)
{
unitOfWork.RollBack();
LoggerService.Log(e);
return View();
}
}
}
If this works fine then there is another issue I am concerned of. So, if I can make my services as instances per lifetime (except DbContext), is there any issue to apply async-await on every method inside of the services to make them non-blocking methods. I am asking this if there is any issue using async-await for the dbContext instance, so, for example, I would have something like this:
public async MyModel GetMyModel()
{
var result = //await on a new task which will use dbcontext instance here
return Mapper.Map<MyModel>(result);
}
Any advice or suggestion is much appreciated!
I'd approach the issue from a distance.
There are some architectural choices which can make your life easier. In web development it's practical to design your application to have stateless service layer (all the state is persisted in DB) and to fit the one HTTP request, one business operation principle (in other words one service method for one controller action).
I don't know how your architecture looks (there's not enough info in your post to determine) but chances are it meets the criteria I described above.
In this case it's easy to decide which component lifetime to choose: DbContext and service classes can be transient (InstancePerDependency in terminology of Autofac) or per request (InstancePerRequest) - it doesn't really matter. The point is that they have the same lifetime so the problem of captive dependencies doesn't arise at all.
Further implications of the above:
You can just use ctor injection in your service classes without worries. (Anyway, service locator pattern would be the last option after investigating lifetime control possibilities like lifetime scopes and IOwned<T>.)
EF itself implements the unit of work pattern via SaveChanges which is suitable most of the cases. Practically, you only need to implement an UoW over EF if its transaction handling doesn't meet your needs for some reason. These are rather special cases.
[...] is there any issue to apply async-await on every method inside of the
services to make them non-blocking methods.
If you apply the async-await pattern consistently (I mean all async operations are awaited) straight up to your controller actions (returning Task<ActionResult> instead of ActionResult), there'll be no issues. (However, keep in mind that in ASP.NET MVC 5 async support is not complete - async child actions are not supported.)
The answer, as always, is it depends... This configuration can work if:
Your scopes are created within the request boundary. Is your unit of work creating a scope?
You don't resolve any of your InstancePerLifetimeScope services before creating your scope. Otherwise they potentially live longer than they should if you create multiple scopes within the request.
I personally would just recommend making anything that depends on DbContext (either directly or indirectly) InstancePerRequest. Transient would work as well. You definitely want everything within one unit of work to be using the same DbContext. Otherwise, with Entity Framework's first level cache, you may have different services retrieving the same database record, but operating on different in-memory copies if they're not using the same DbContext. Last update would win in that case.
I would not reference your container in MyService, just constructor inject it. Container references in your domain or business logic should be used sparingly and only as a last resort.
My application uses Entity Framework. Since I want my DbContext to be reused across a single request, I registered it as Lifestyle.Scoped, as shown below:
container.Register<MyDbContext>(Lifestyle.Scoped);
Other classes get this MyDbContext injected. As example, see the following repository:
ApplicationsRepository is:
public class ApplicationsRepository : IApplicationsRepository
{
private readonly MyDbContext _dbContext;
public ApplicationsRepository(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public void Save()
{
_dbContext.Save();
}
public Application GetByName(string appName)
{
var dbApplication = _dbContext.APPLICATIONS.FirstOrDefault(a => a.NAME == appName);
return ApplicationMapper.MapApplicationFromAPPLICATIONS(dbApplication);
}
}
But there are countless other classes that either take a dependency on MyDbContext. Other classes might not depend on MyDbContext directly, but do get injected with a class that does depend on MyDbContext.
My questions is: what kind of lifestyle management should I use for these classes and how implements it?
There are 3 basic lifestyles to choose from, Transient, Scoped and Singleton, as you already learned by reading this.
Which lifestyle to choose for a particular component, depends on several factors:
Whether or not the component can be used safely across requests/threads
Whether or not the component contains state that needs to be shared across threads
The lifestyle of the component's dependencies.
First of all, the lifestyle your component needs is a choice you need to make based on how that component is designed. Some components simply can't be reused and should always be re-created when requested. This typically holds for framework types such as MVC Controllers. Although there is typically one controller per request, it is possible to request other controllers and this requires new instances to be created. This is equivalent to the Transient lifestyle.
Other components or classes that you register need to be reused. Unit of Work implementations such as Entity Framework's DbContext will typically need to be reused for the duration of a complete request. You can read a detailed discussion about why you want to reuse a DbContext here. This is equivalent to the Scoped lifestyle.
Other components are completely stateless or immutable and can be reused by all threads in the application in parallel without any trouble. Other components might be statefull or mutable, but are designed with thread-safety in mind. They might implement an application-wide cache that needs to be updated, and access to the component is protected with locks. This means you only have one instance reused throughout the application. This is equivalent to the Singleton lifestyle.
Dependencies however complicate lifestyle choice of a component, because a component's lifestyle should never be longer than any of its dependencies. Failing to obey to this rule, causes Captive Dependencies, or Lifestyle Mismatches as Simple Injector calls them.
This means that even if you determined a component to be eligible to be a Singleton, it can only be as long as its shortest dependency. In other words, if the component has a Scoped Dependency, it itself can only be either Scoped or Transient. Simple Injector will detect if you misconfigure this.
This does mean however that the choice you make for a component, does propagate up the call stack to the component's consumers.
In general, this results in a structure where the leaf components in an application's object graphs are Scoped and Singleton, while the root types are Transients. If you are structuring your object graphs in this way, you are following the Closure Composition Model.
There is an alternative DI Composition Model, and it is called the Ambient Composition Model. When practicing this model you, for the most part, keep state out of your components, and instead store state in Ambient State, which is controlled by the Composition Root. Both composition models have their advantages and disadvantages.
I'm trying to instantiate a SecondViewModel from a MainViewModel injecting in this second one paramaters that are services registered in the IoCContainer and objects from the MainVM.
The code is something of this kind:
class MainViewModel
{
public MainViewModel()
{
}
private string message = "the message";
public string Message { get; set; }
}
class SecondViewModel
{
public SecondViewModel(IService service, string message)
{
}
}
now, i know i can make the IoC Container inject a SecondViewModelFactory (that carries the service instance) into the MainViewModel, so it can create the SVM through it, but what if the implementation of IService is very heavy and i don't want to instantiate it but when i really need it.
And what if i have to instantiate other ViewModels in a similar way? Do I have to create tons of VMFactories and constructor's parameters?
And in case I use a generic ViewModelFactory, it would need to be instantiated passing all the services needed by every ViewModel I have, regardless if they will be created or not.
Do you know any better solution to my case?
In general, the creation of services should not be heavy. Their constructor should do nothing more than storing the incoming dependencies. If it uses some heavy resources in the background, they shouldn't be accessed through the constructor. This keeps the constructor simple (prevents you from having to test it) and allows the object graph to be composed very rapidly.
If there is really no way around this, there are basically two patterns you can apply:
1. Factories
You can inject a factory to delay the creation of a type. Factories are also useful when objects are created that should be controlled explicitly (for instance, instances that should be disposed as soon as possible). There are several ways of creating factories. Some people like to inject Func<T> or Lazy<T> dependencies into their services, but I find this too implicit. I rather inject an ISomeServiceFactory, since I find this more readable. Downside is that you need to define a new interface for this. However, if you find yourself having many factory interfaces, you probably have a problem in your design anyway.
2. Proxies
Instead of creating a factory, you can hide the service behind a proxy. This proxy can implement the same interface as the service and will do the delayed execution for you. This prevents you from letting the application take a dependency on a different interface (an IServiceFactory or Lazy<T> for instance). Especially Lazy<T> leaks details about the creation into the consumer of such a dependency. You can still inject a Lazy<T> into this proxy, if that's convenient. That's not a problem. That proxy would typically be part of your composition root and the rest of your application would still be dependend on your IService and not your Lazy<IService>.
Please be aware that the use of factories, proxies and lazy initiation does complicate the wiring of the container. So don't use if unless you measured that you really need it. They complicate things, because of the indirection, which makes it harder to follow interlectually. And they make it harder to verify your configuration using automated tests. For more information about verifying your container, take a look here and here.
Most IoC Containers supports Lazy dependency to with Lazy<> to avoid creating expensive class immediately.
So in your code, you can make lazy for your expensive IService:
class SecondViewModel
{
public SecondViewModel(Lazy<IService> service, string message)
{
}
}
You can use some popular IoC Containers and see how they support lazy loading: Autofac or NInject
I am aware that a thousand and one questions relating to this topic have been asked, but I have gone through at least a dozen and am still not connecting the dots. I am trying to setup dependency injection for entity contexts.
I have always created my entity context as I have seen in the MS tutorials, like so:
public class UserController : Controller
{
private DbEntities db = new DbEntities();
}
Recent reading has told me that this is no longer (if it ever was) the best practice, and a dependency injection method should be used. Ninject is mentioned often, but I am seeing how you move from what I have, to the example give in the Ninject documentation.
It should look like this when I am done, right?
public class UserController : Controller
{
private DbEntities db;
public UserController(DbEntities context)
{
db = context;
}
}
The documentation starts out with "In the previous step we already prepared anything that is necessary for controller injection." which is confusing as hell, since the previous step was installation. I used the Nuget method to install, but I don't know what it means when it says "Now load your modules or define bindings in RegisterServices method." How do I do that, and is entity a module or a binding? The documentation feels so sparse.
I am sorry if I skipped over something critical in the docs, I've been bouncing between forums for hours trying to figure out this one step.
I used the Nuget method to install, but I don't know what it means
when it says "Now load your modules or define bindings in
RegisterServices method." How do I do that, and is entity a module or
a binding?
The Nuget installation actually does quite a lot of things for you already. The most important thing is that it sets up Ninject as controller factory, which means that Ninject will create your controllers and is able to pass in all dependencies you have registered with it.
If you check the App_Start folder you will find a file NinjectMVC3.cs. There is already an empty method RegisterServices() which you can use to register your dependencies.
For your example you must be able to resolve DbEntities. The easiest most basic way to do this is:
kernel.Bind<DbEntities>().ToSelf();
That said you really should pass in an interface to your controller so the controller does not depend on Entity Framework, using abstractions and registering a concrete class to use in the IoC container is one of the main reasons for dependency injection.
This should give you a start - the documentation you link to seems a bit outdated. I would recommend looking at the Ninject MVC3 sample on github.
Dependency Injection can seem confusing at first, but it's really actually quite simple.
A Dependency Injection "container" is basically a generic factory, with various object lifetime management features. Ninject, in particular, uses the syntax kernel.Bind() to confgure this factory. When you say kernel.Bind<DbEntities>().ToSelf() this means that Ninject will create an instance of the bound type (DbEntities in this case) whenever that type is requested. This request typically looks like this:
var entities = kernel.Get<DbEntities>(); // Note: don't do this, just an example
At it's core, this is what Dependency Injection is. A generic factory that can instantiate arbitrary types.
However, there is a lot more to it than that. One nice feature of Dependency Injection is that it will also instantiate any dependent types in the process. So, suppose you have a controller, and that controller has a dependency on DbEntities. Well, when a controller is instantiated by the DI Framework, it will also instantiate the dependent DbEntities. See the code below. When the MyController is instantiated, the DbEntities will automatically get instantiated (assuming you have bound the DbEntities class to self in the DI Configuration)
var controller = kernel.Get<MyController>();
public class MyController : Controller {
private DbEntities _entities;
public MyController(DbEntities entities) {
_entities = entities;
}
}
This is recursive. Any class that gets instantiated that has any objects that it itself might depend on get instantiated as well, and so on, and so on until finally, everything has what it needs to do its job.
Now, the great thing about MVC is that it has a way built-in to use any DI container automatically. You don't have to call kernel.Get because the framework does it for you when it creates the controllers when a request comes in. This feature is called IDependencyResolver, and is an interface that the MVC framework uses to allow third party DI containers to be used by the framework.
If you install Ninject by using the Nuget package Ninject.MVC3 then it will automatically configure all this for you, and you need only add your bindings to the RegisterServices() section of NinjectMVC3.cs
There's a lot more to it than this, but this should give you a basic understanding. Dependency Injection allows you to forget about the details of managing when objects are created and destroyed, you just specify in your constructor which dependencies you need, and assuming you have bindings for them in your configuration, MVC will take care of creating and destroying them for you. You just use them.
EDIT:
To be clear, I don't recommend you use the examples I give above. They are just simple illustrations of how DI works. In particular, the Get() syntax is known as "Service Location" and is considered to be bad. However, ultimately some code, somewhere must call Get(), it's just buried deep in the framework.
As Adam mentions, binding directly to the data entities context isn't a great idea, and you should eventually move to using an interface based approach.
I would never inject a concrete type here - you are directly coupling to a data access implementation.
Instead bind to IDbContext (or IUnitOfWork) - these are interfaces you define with a backing concrete implementation of DbContext, this way you can easily abstract away what technology you are using, making it more swappable, testable, maintainable, etc.
for ex:
http://blogs.planetcloud.co.uk/mygreatdiscovery/post/EF-Code-First-Common-Practices.aspx#disqus_thread