The operation cannot be completed because the DbContext has been disposed. nopcommerce - nopcommerce

I am getting DbContext has been disposed error when I try to get data from database using below code that have mention.
How to solved this issue ?
public class ExampleService<T> where T : Example
{
protected readonly IRepository<T> _exampleRepository;
public ExampleService()
{
_exampleRepository= EngineContext.Current.Resolve<IRepository<T>>();
}
public IList<T> GetService()
{
var query = _exampleRepository.Table;
return query.ToList();
}
}

I think there is not enough code in your sample. It should work perfectly if you're getting ExampleService from the dependency scope.
So my answer is this: Use dependency injection at your constructor instead of using a ResourceLocator. If you declare the dependencies at the constructor instead and still have problems, like for instance, not receiving an instance of IRepository then you can be sure you're instantiating ExampleService the wrong way, outside of the autofac scope, and that is a sure cause for trouble.

The issue is some parts of the object should be disposed, while it still in use.
Try to always resolve the service in this way:
protected readonly IRepository<T> _exampleRepository;
To
var _exampleRepository = EngineContext.Current.Resolve<IRepository<T>>();
Hope this helps!

Related

EntityFramework dependency injection of DatabaseContext on Asp.Net

i have not much knowledge about Asp and Entity Framework so i really cant figure out what i have to do.
My problem is accessing database context out of main asp method -
There is how db context created and used in Program.cs (Main)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<DatabaseContext>(
options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultDataSource"))
);
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = services.GetRequiredService<DatabaseContext>();
context.Database.EnsureCreated();
}
so my problem is kinda that i making "options" for DatabaseContext constructor out of "builder.Configuration"
But what do i do when i need to acces db from other script? DatabaseContext requires config but i just dont know how to get it outside of that builder.
one guy suggested me to use Dependency Injection, i have looked but i just cant get how to do it properly, like i make a class where i initialize db context, but i still need to somehow make a config here and i really have no clue how.
It could be really stupid question but i really cant figure it out for a couple of days :D
I`ve tried to make DbContext without a config but it gives error
I don't know what you tried, but I think this might be what you want.
Assuming your DatabaseContext class is the most basic, and defines a table
Users in it:
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options)
: base(options)
{
}
public DbSet<Models.User> Users { get; set; }
}
Then you register it in Program.cs:
builder.Services.AddDbContext<DatabaseContext>(
options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultDataSource"))
);
You can generate your database by migrating and updating the database(Of course you can also manually create):
Add-Migration InitialCreate
Update-Database
Then you can access your database in other classes through dependency injection, such as in the controller:
public class HomeController : Controller
{
private readonly DatabaseContext _databaseContext;
public HomeController(DatabaseContext databaseContext)
{
_databaseContext = databaseContext;
}
public IActionResult Index()
{
var user = _databaseContext.Users.ToList();
return View();
}
}
For more details about dependency injection, you can refer to this document.

Why is the IConfiguration object null after injecting it to DbContext? [ASP.NET Core 3.1]

Before posting this question I have gone through multiple posts that are similar. My question focuses on "why is it happening despite applying the common and possibly right solution?".
I am developing a .NET Core 3.1 web app. I have a DbContext named 'SkipQContext'. I am trying to access the connection string from appsettings.json in the SkipQContext file using Configuration object.
For that, I have injected IConfiguration as a service to the SkipQContext constructor.
Constructor:
private readonly string ConnectionString;
public SkipQContext()
{
}
public SkipQContext(DbContextOptions<SkipQContext> options, IConfiguration configuration)
: base(options)
{
ConnectionString = configuration.GetConnectionString("DefaultConnection");
}
I have also registered in ConfigureServices method of Startup class.
services.AddSingleton(Configuration);
Now when I instantiate SkipQContext in one of my repository classes, the default constructor of SkipQContext is called. When I try to fetch data using it, I get the "IConfiguration object is null."
I applied breakpoints in ConfigureServices method and can see that the IConfiguration object has the connection string value.
My first question is, why is it null in SkipQContext when I am registering it in ConfigureServices and also injecting it in SkipQContext constructor? Multiple answers online state this as the right method.
Also, I am thinking, I might not be instantiating the SkipQContext rightly. As my statement :
SkipQContext db = new SkipQContext();
hits the default constructor of SkipQContext which is empty and not the overloaded constructor where IConfiguration is injected.
P.S. If the last question is dumb. I am still a bit unclear about how dependency injection works in .NET Core.
Also, I am thinking, I might not be instantiating the SkipQContext rightly. As my statement:
SkipQContext db = new SkipQContext();
hits the default constructor of SkipQContext which is empty and not the overloaded constructor where IConfiguration is injected.
You are right, this is not how dependency injection is supposed to work. Whenever you do new Something, then you are explicitly going around dependency injection. The main point about dependency injection is that a component that has a dependency (e.g. a database context) does not need to create that dependency itself, or even know how to create that dependency itself.
When you call new SkipQContext(), you are explicitly creating that depenndency, so you are tightly coupled to that SkipQContext and whatever that context needs in order to work properly (in this case, it needs DbContextOptions and IConfiguration). What you want instead is components to be loosely coupled to their dependencies. So you just declare what dependencies you need and require that someone or something else fulfills these dependencies for you. And that’s exactly where dependency injection comes in:
With dependency injection, you have a “dependency injection container” which takes care of creating all the dependencies that you or some component may require. You configure the container in a central location, in Startup.ConfigureServices, and then you are able to simply declare what dependencies you need via a service’s constructor. But in order for the container to provide these dependencies to that service, the service will have to be created by the container itself.
So what you will see is that you will basically have to consume everything through dependency injection. But this also makes it easy to realize when you are not using dependency injection: Whenever you write new Something, then that something won’t be created by the container and as such won’t have its dependencies automatically fulfilled. Depending on what that something is that might be what you want, or maybe not (e.g. creating a List<string> or a DTO object is something you want to do directly, creating a service or something that has other dependencies likely isn’t).
Coming back to your problem, in order to have the DI container take care of the dependencies in the constructor of SkipQContext, you will have to let the DI container create that context for you. So you cannot create it with new but instead you will have to depend on it by adding it to the constructor of whatever component you need it in.
E.g. if you have a controller, just add it as a dependency there:
public class HomeController : Controller
{
private readonly SkipQContext _db;
public HomeController(SkipQContext db)
{
_db = db;
}
public async Task<IActionResult> Index()
{
var items = await _db.Items.ToListAsync();
return View(new IndexViewModel
{
Items = items,
});
}
}
One final note regarding your database context: If you register the database context correctly with the DI container, then it will already be configured using the DbContextOptions that gets passed to the constructor. These options will also include the connection string the context needs to open the database connection. So you do not need to pass the IConfiguration manually or extract the connection string there. It will be automatically done for you by EF Core.
A proper context setup could look like this (in ConfigureServices):
services.AddDbContext<SkipQContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
There is no need to instantiate the Configuration as a Singleton, the Default builder of WebHost already inject the configuration in the request , your Startup Class should look like this
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
string conn = Configuration.GetConnectionString("NAME OF YOUR CONNECTION STRING IN THE application.json FILE");
services.AddDbContext<CLASSOFURDBCONTEXT>(config =>
{
config.UseSqlServer(conn);
});
}
}
And your dbcontext should have the following constructor
public YourDbContext(DbContextOptions<YourDbContext> options) : base(options)
{
}
Then you only need to call the DbContext in a controller or a service and the DI will do the rest
As per why your IConfiguration throw the null reference exception i can think of 2 possibilities. Either you need to do the other kind instanciation which would be like this
services.AddSingleton<IConfiguration,Configuration>();
Or maybe it is because you are not using DI into the DbContext itself, you shouldnt need to do the new YourContextDbContext(). You should just simply put it in the constructor of the service or controller and it should work "magically" without you actually need to make an instance of it.

How do you inject a view dependency into Presenter (MVP) in ASP.NET Web Forms using Simple Injector or Microsoft.Extensions.Dependency?

The following example shows a scenario where I'm trying to implement a DI container. In this case, I'm trying to use Simple Injector or Microsoft.Extensions.DependencyInjection DI Container. I've seen code examples that start hitting around the target, such as here, but no bullseye as of yet.
Below is a general code sample that I would like to modify to use one of the aforementioned DI containers (Used Simple Injector for example). I could move the view out of the presenter constructor and set it as a property. However, I was hoping for a more eloquent solution also it is a dependency that needs to be injected.
I know .NET 4.7.2 has increased DI support functionality but the biggest benefit seems to be allowing dependencies to be easily injected into pages/user controls. For MVP architecture I need the concrete class of the page tied to its view interface so the DI container can resolve and pass into the presenter, as the presenter depends on the view. I've not seen an example of this implemented well other than Unity using its DependencyOverride, which can pass the concrete class at runtime.
public partial class UserLoginView : IUserLoginView
{
private UserLoginPresenter _userLoginPresenter;
protected override void OnLoad(EventArgs e)
{
//This is my problem:
//An error will be thrown "...contains the parameter with name
//'view' and type IUserLoginView, but IUserLoginView is not
//registered..."
_userLoginPresenter = SimpleInjectorDependencyInjector
.GetInstance<IDeveloperTestStatusPresenter>();
}
}
public class UserLoginPresenter : IUserLoginPresenter
{
private readonly IUserLoginView view;
private readonly IUserService _userService;
public UserLoginPresenter(IUserLoginView userLoginView,
IUserService userService)
{
this.view = userLoginView;
this._userService = userService;
}
public static class SimpleInjectorDependencyInjector
{
private static readonly Container container = new Container();
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
//Assume this is called from App on start
public static void RegisterClasses()
{
container
.Register<IUserLoginPresenter, UserLoginPresenter>();
container
.Register<IUserService, UserService>();
}
}
I was able to accomplish what I was looking for using Microsoft.Extensions.DependencyInjection Container.
In my MSDependencyInjector wrapper class, I used the ActivatorUtilities extension.
public static T GetService<T, I>(I interfaceInstance)
{
return ActivatorUtilities.CreateInstance<T>(container, interfaceInstance);
}
Implemented in my page's partial class I wrote:
_userLoginPresenter = MSDependencyInjector.GetService<UserLoginPresenter,
IUserLoginView>(this);
A Caveat: The 'T' parameter of createInstance wants the concrete class type not the interface. This caused hours of frustration, prompting the creation of this question in the first place. MS documentation isn't the greatest but I definitely misread.
I'm not sure how to implement something as straightforward in Simple Injector and would be interested in knowing. Based on my reading I not sure if my solution isn't something like a service locator, which depending on which camp you are from should be avoided. However, if the implementation of this can be contained for just solving the need for this MVP paradigm then it is my hope all will be well.

How to get ApplicationDbContext out of the Owin pipeline

This has to be simple, but I'm going bug-eyed trying to find the answer. How does a controller action get a reference to the per-request ApplicationDbContext that was stashed in the Owin pipeline?
EDIT: Ok, I think I'm getting closer... or maybe not... All of my Googling seems to lead to this blog post, which sez to use:
var dbContext = context.Get<ApplicationDbContext>();
where context is apparently an instance of Microsoft.Owin.IOwinContext. So I tried:
var db = HttpContext.GetOwinContext().Get<ApplicationDbContext>();
But the Get<T> method requires a string key parameter. :(
And the answer (apparently) is... You need to add this using statement to get it to work:
using Microsoft.AspNet.Identity.Owin;
so a complete example would look like:
using Microsoft.AspNet.Identity.Owin;
public class HomeController : Controller
{
public ActionResult Index()
{
var context = HttpContext.GetOwinContext().Get<ApplicationDbContext>();
DoSomething(context); // Use the context object; do not dispose it!
return View();
}
}

How to pass unit of work container into constructor of repository using dependency injection

I'm trying to work out how to complete my implementation of the Repository pattern in an ASP.NET web application.
At the moment, I have a repository interface per domain class defining methods for e.g. loading and saving instances of that class.
Each repository interface is implemented by a class which does the NHibernate stuff. Castle Windsor sorts out the DI of the class into the interface according to web.config. An example of an implemented class is provided below:
public class StoredWillRepository : IStoredWillRepository
{
public StoredWill Load(int id)
{
StoredWill storedWill;
using (ISession session = NHibernateSessionFactory.OpenSession())
{
storedWill = session.Load<StoredWill>(id);
NHibernateUtil.Initialize(storedWill);
}
return storedWill;
}
public void Save(StoredWill storedWill)
{
using (ISession session = NHibernateSessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.SaveOrUpdate(storedWill);
transaction.Commit();
}
}
}
}
As pointed out in a previous thread, the repository class needs to accept an unit of work container (i.e. ISession) rather than instantiating it in every method.
I anticipate that the unit of work container will be created by each aspx page when needed (for example, in a property).
How do I then specify that this unit of work container instance is to be passed into the constructor of StoredWillRepository when Windsor is creating it for me?
Or is this pattern completely wrong?
Thanks again for your advice.
David
I have a persistence framework built on top of NHibernate that is used in a few Web apps. It hides the NH implementation behind an IRepository and IRepository<T> interface, with the concrete instances provided by Unity (thus I could in theory swap out NHibernate for, say, Entity Framework fairly easily).
Since Unity doesn't (or at least the version I'm using doesn't) support the passing in of constructor parameters other than those that are dependency injections themselves, passing in an extant NH ISession isn't possible; but I do want all objects in the UOW to share the same ISession.
I solve this by having a controlling repository class that manages access to the ISession on a per-thread basis:
public static ISession Session
{
get
{
lock (_lockObject)
{
// if a cached session exists, we'll use it
if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY))
{
return (ISession)PersistenceFrameworkContext.Current.Items[NHibernateRepository.SESSION_KEY];
}
else
{
// must create a new session - note we're not caching the new session here... that's the job of
// BeginUnitOfWork().
return _factory.OpenSession(new NHibernateInterceptor());
}
}
}
}
In this example, PersistenceFrameworkContext.Current.Items accesses an IList<object> that is stored either ThreadStatic if not in a Web context, or within HttpContext.Current.Items if it is in a Web context (to avoid thread-pool problems). The first call to the property instantiates the ISession from the stored factory instance, subsequent calls just retrieve it from storage. The locking will slow things down slightly but not as much as just locking an appdomain-scoped static ISession instance.
I then have BeginUnitOfWork and EndUnitOfWork methods to take care of the UOW - I have specifically disallowed nested UOWs because frankly they were a pain to manage.
public void BeginUnitOfWork()
{
lock (_lockObject)
{
if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY))
EndUnitOfWork();
ISession session = Session;
PersistenceFrameworkContext.Current.Items.Add(SESSION_KEY, session);
}
}
public void EndUnitOfWork()
{
lock (_lockObject)
{
if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY))
{
ISession session = (ISession)PersistenceFrameworkContext.Current.Items[SESSION_KEY];
PersistenceFrameworkContext.Current.Items.Remove(SESSION_KEY);
session.Flush();
session.Dispose();
}
}
}
Finally, a pair of methods provide access to the domain-type-specific repositories:
public IRepository<T> For<T>()
where T : PersistentObject<T>
{
return Container.Resolve<IRepository<T>>();
}
public TRepository For<T, TRepository>()
where T : PersistentObject<T>
where TRepository : IRepository<T>
{
return Container.Resolve<TRepository>();
}
(Here, PersistentObject<T> is a base class providing ID and Equals support.)
Access to a given repository is thus in the pattern
NHibernateRepository.For<MyDomainType>().Save();
This is then facaded over such that you can use
MyDomainType.Repository.Save();
Where a given type has a specialised repository (ie needs more than it can get from IRepository<T>) then I create an interface deriving from IRepository<T>, an extending implementation inheriting from my IRepository<T> implementation, and in the domain type itself I override the static Repository property using new
new public static IUserRepository Repository
{
get
{
return MyApplication.Repository.For<User, IUserRepository>();
}
}
(MyApplication [which is called something less noddy in the real product] is a facade class which takes care of supplying the Repository instance via Unity so you have no dependency on the specific NHibernate repository implementation within your domain classes.)
This gives me full pluggability via Unity for the repository implementation, easy access to the repository in code without jumping through hoops, and transparent, per-thread ISession management.
There's lots more code than just what's above (and I've simplified the example code a great deal), but you get the general idea.
MyApplication.Repository.BeginUnitOfWork();
User user = User.Repository.FindByEmail("wibble#wobble.com");
user.FirstName = "Joe"; // change something
user.LastName = "Bloggs";
// you *can* call User.Repository.Save(user), but you don't need to, because...
MyApplication.Repository.EndUnitOfWork();
// ...causes session flush which saves the changes automatically
In my Web app, I have session-per-request, so BeginUnitOfWork and EndUnitOfWork get called in BeginRequest and EndRequest respectively.
I have a pretty similar structure to yours, and here's how I solve your question:
1) To specify my container on each method, I have a separate class ("SessionManager") which I then invoke via a static property. By doing so, here's an example using my Save implementation:
private static ISession NHibernateSession
{
get { return SessionManager.Instance.GetSession(); }
}
public T Save(T entity)
{
using (var transaction = NHibernateSession.BeginTransaction())
{
ValidateEntityValues(entity);
NHibernateSession.Save(entity);
transaction.Commit();
}
return entity;
}
2) My container is not created on each ASPX page. I instantiate all of my NHibernate goodness on the global.asax page.
** A few more things spring up **
3) You don't need to have a helper to instantiate the Load. You might as well use Get instead of Load. More information # Difference between Load and Get.
4) Using your current code, you would have to repeat pretty much the same code for each domain object you need (StoredWillRepository, PersonRepository, CategoryRepository, etc..?), which seems like a drag. You could very well use a generic class to operate over NHibernate, like:
public class Dao<T> : IDao<T>
{
public T SaveOrUpdate(T entity)
{
using (var transaction = NHibernateSession.BeginTransaction())
{
NHibernateSession.SaveOrUpdate(entity);
transaction.Commit();
}
return entity;
}
}
In my implementation, I could then use something like:
Service<StoredWill>.Instance.SaveOrUpdate(will);
Technically, the answer to my question is to use the overload of container.Resolve which allows you to specify the constructor argument as an anonymous type:
IUnitOfWork unitOfWork = [Code to get unit of work];
_storedWillRepository = container.Resolve<IStoredWillRepository>(new { unitOfWork = unitOfWork });
But let's face it, the answers provided by everyone else have been much more informative.

Resources