AutoFac DbContext issue - cannot be used while the model is creating - c#

I'm having a few issues getting started with AutoFac and IoC. We've got a working application however, I'm starting from scratch with this one and can't see where the differences between the two are.
I am testing this with a simple AJAX page which is calling the Service layer via a ServiceStack API. When using MockRepositories this works fine so I know that side of things is working.
However when I replace the mocks with ones that use Entity Framework, although all the registrations appear to be correct and working, I get the error "The context cannot be used while the model is being created."
I have included my code below:
public class SomeObject
{
public int Id { get; set; }
}
public class IoCExampleContext : DbContext, IIoCExampleContext
{
public IDbSet<SomeObject> SomeObjects { get; set; }
static IoCExampleContext()
{
Database.SetInitializer(new IoCExampleDatabaseInitilizer());
}
public IoCExampleContext(string connectionStringName)
: base(connectionStringName)
{
Configuration.ProxyCreationEnabled = false;
}
public IoCExampleContext()
: this("name=IoCExample")
{}
public string ConnectionString
{
get { return Database.Connection.ConnectionString; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
BuildModels(modelBuilder);
}
private void BuildModels(DbModelBuilder builder)
{
var typeToUse = typeof(SomeObjectModelBuilder);
var namespaceToUse = typeToUse.Namespace;
var toReg = Assembly
.GetAssembly(typeToUse)
.GetTypes()
.Where(type => type.Namespace != null && type.Namespace.StartsWith(namespaceToUse))
.Where(type => type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (object configurationInstance in toReg.Select(Activator.CreateInstance))
{
builder.Configurations.Add((dynamic)configurationInstance);
}
}
}
public class IoCExampleDatabaseInitilizer : CreateDatabaseIfNotExists<IoCExampleContext>
{
protected override void Seed(IoCExampleContext context)
{
}
}
public interface IRepository<TEntity> where TEntity : class
{
IQueryable<TEntity> GetQuery();
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);
// ...Various "standard" CRUD calls
}
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected DbContext _context;
private readonly DbSet<TEntity> _dbSet;
public GenericRepository(DbContext context)
{
_context = context;
_dbSet = _context.Set<TEntity>();
}
public IQueryable<TEntity> GetQuery()
{
return _dbSet;
}
public IEnumerable<TEntity> GetAll()
{
return GetQuery().AsEnumerable();
}
public IEnumerable<TEntity> Where(Expression<Func<TEntity, bool>> predicate)
{
return GetQuery().Where(predicate);
}
// ...Various "standard" CRUD calls
public void Dispose()
{
OnDispose(true);
}
protected void OnDispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}
public class DependencyBootstrapper
{
private ContainerBuilder _builder;
public IContainer Start()
{
_builder = new ContainerBuilder();
_builder.RegisterFilterProvider();
RegisterControllers();
return _builder.Build();
}
private void RegisterControllers()
{
RegisterAssembly(Assembly.GetExecutingAssembly());
_builder.RegisterModelBinderProvider();
RegisterPerLifetimeConnections();
RegisterRepositories();
RegisterServices();
}
private void RegisterAssembly(Assembly assembly)
{
_builder.RegisterModelBinders(assembly);
_builder.RegisterControllers(assembly);
}
private void RegisterRepositories()
{
_builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IRepository<>));
_builder.RegisterType<GenericRepository<SomeObject>>().As<IRepository<SomeObject>>();
//... More registrations
}
private void RegisterServices()
{
_builder.RegisterType<SomeObjectService>().As<ISomeObjectService>();
//... More registrations
}
private void RegisterPerLifetimeConnections()
{
const string connectionStringName = "IoCExample";
_builder.RegisterType<IoCExampleContext>()
.As<DbContext>()
.WithParameter("connectionStringName", connectionStringName)
.InstancePerLifetimeScope();
_builder.Register(c => new HttpContextWrapper(HttpContext.Current))
.As<HttpContextBase>();
}
}
I don't know if it's relevant but as we can't get access to the global.asax methods we're calling the bootstrapper through PreApplicationStartMethod.OnPreApplicationStart (which as far as I am aware, is pretty much the same thing as Application_Start).
What's a little concerning is that when I enable Multiple Active Result Sets on the connection string it works -which would suggest to me that I'm registering the DbContext incorrectly and it's spanning multiple contexts.
Can anyone spot where I'm going wrong?

The connection string is the issue. Ensure you've set it up correctly in your web/app.comfig.

Related

Circular component dependency detected Repository pattern with autofac dependency injections

I am working on implementing the generic repository pattern with db Context and Autofac DI, and I am using the constructor based on dependency injections.
I have created the three layers repository pattern which are:
Infrastructure layer
Model layer
Services layer
Now, I am using this architecture in MVC web application when I try to pass the IContactService interface in ContactController and run the application.
I am getting the circular dependency detected error. Followings are my project code.
Repository code:
public class Repository<T> : IRepository<T> where T : class
{
private InvoiceBillingDbContext db;
private DbSet<T> dbSet;
public Repository()
{
db = new InvoiceBillingDbContext();
dbSet = db.Set<T>();
}
public IEnumerable<T> GetAll()
{
return dbSet.ToList();
}
public T GetById(object Id)
{
return dbSet.Find(Id);
}
public void Insert(T obj)
{
dbSet.Add(obj);
Save();
}
public void Update(T obj)
{
db.Entry(obj).State = EntityState.Modified;
Save();
}
public void Delete(object Id)
{
T getObjById = dbSet.Find(Id);
dbSet.Remove(getObjById);
}
public void Save()
{
db.SaveChanges();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (this.db != null)
{
this.db.Dispose();
this.db = null;
}
}
}
public void AddRange(List<T> obj)
{
dbSet.AddRange(obj);
Save();
}
public IEnumerable<T> Get(Expression<Func<T, bool>> predicate)
{
return dbSet.Where(predicate);
}
}
Interface IRepository
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
T GetById(object Id);
IEnumerable<T> Get(Expression<Func<T, bool>> predicate);
void Insert(T obj);
void AddRange(List<T> obj);
void Update(T obj);
void Delete(Object Id);
void Save();
}
My ContactRepository
public class ContactRepository:Repository<Contact>, IContactRepository
{
private IContactRepository _contractRepo;
public ContactRepository(IContactRepository contractRepo)
{
this._contractRepo = contractRepo;
}
}
My ContactRepository Interface
public interface IContactRepository:IRepository<Contact>
{
}
My Contact Service
public interface IContactService
{
void AddContact(Contact contact);
IEnumerable<Contact> GetContactsByTypeId(int typeId);
}
public class ContactService : IContactService
{
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
this._contactRepository = contactRepository;
}
public void AddContact(Contact contact)
{
_contactRepository.Insert(contact);
}
public IEnumerable<Contact> GetContactsByTypeId(int typeId)
{
return _contactRepository.Get(i => i.TypeID == typeId);
}
}
My Controller
public class ContactController : Controller
{
// GET: Contact
private IContactService _contactService;
public ContactController(IContactService contactService)
{
this._contactService = contactService;
}
public ActionResult Index()
{
return View(new ContactViewModel());
}
public ActionResult AddContact(ContactViewModel contact)
{
if (ModelState.IsValid)
{
var _contactMapper = Mapper.Map<ContactViewModel, Contact>(contact);
_contactService.AddContact(_contactMapper);
ViewBag.Message = "Successfully Saved";
return View("Index",new ContactViewModel());
}
ViewBag.Message = "Error Occur Please try Again!";
return View("Index", new ContactViewModel());
}
}
And Autofac Dependency Injection
public static void ConfigureContainer()
{
var builder = new ContainerBuilder();
// Register all controllers in the Mvc Application assembly
builder.RegisterControllers(typeof(MvcApplication).Assembly);
// Registered Warehouse Reservoir Service
builder.RegisterType<InvoiceRepository>().As<IInvoiceRepository>();
// Registration Service Layer Service
builder.RegisterType<InvoiceService>().As<IInvoiceService>();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
// Registered Warehouse Reservoir Service
builder.RegisterType<JournalVoucherRepository>().As<IJournalVoucherRepository>();
// Registration Service Layer Service
builder.RegisterType<JournalVoucherService>().As<IJournalVoucherService>();
// Registered Warehouse Reservoir Service
builder.RegisterType<ContactRepository>().As<IContactRepository>();
// Registration Service Layer Service
builder.RegisterType<ContactService>().As<IContactService>();
// Registration filter
builder.RegisterFilterProvider();
var container = builder.Build();
// Setting Dependency Injection Parser
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
You've only got one implementation of IContactRepository. You've also got a generic IRepository<T>.
Your implementation of IContactRepository gets another IContactRepository injected into it. So you're recursively resolving the same class and injecting it into itself.
public class ContactRepository:Repository<Contact>, IContactRepository
{
private IContactRepository _contractRepo;
// In order to resolve IContractRepository, the container has to
// resolve another IContractRepository to inject into it.
// And another one to inject into that. It's recursive.
public ContactRepository(IContactRepository contractRepo)
{
this._contractRepo = contractRepo;
}
}
Your example doesn't show how ContactRepository uses the IContactRepository that gets inject into it. But this
public interface IContactRepository:IRepository<Contact>
{
}
reveals that it's using the exact same methods found in IRepository<Contact>, because IContactRepository doesn't have any methods other than those.
So you most likely just need to modify ContactRepository to inject IRepository<Contact>, not IContactRepository.
public class ContactRepository:Repository<Contact>, IContactRepository
{
private IRepository<Contact> _contractRepo;
public ContactRepository(IRepository<Contact> contractRepo)
{
this._contractRepo = contractRepo;
}
}
That could be easy to overlook since both interfaces have exactly the same methods.

Unit of Work and Repository Pattern in MVC controller constructor injection using Unity not doing any changes to database

1.) I am a building new MVC application with 3 tier project architecture having:
Common Project with entities
Business/Service holding interfaces and logic classes and
Data holding repositories, interfaces, DbContext and UnitOfWorkclasses. I am using Unity Config to register dependencies, DbContext and UnitOfWork.
2.) I created a repository for each table and one generic repository that does basic CRUD operations.
Example Entity residing in Common Project:
public class MenuSecd
{
[Key, Column(Order = 0)]
public string prg_module { get; set; }
[Key, Column(Order = 1)]
public int prg_numb { get; set; }
[Key, Column(Order = 2)]
public string menu_level { get; set; }
}
My generic Entity Logic Interface residing in Business Project:
public interface IEntityLogic<T> : ILogic where T : class
{
void Create(T entity);
void Delete(T entity);
IEnumerable<T> GetAll();
void Update(T entity);
}
Entity Logic Class:
public abstract class EntityLogic<T> : IEntityLogic<T> where T : class
{
IUnitOfWork _unitOfWork;
IGenericRepository<T> _repository;
public EntityLogic(IUnitOfWork unitOfWork, IGenericRepository<T> repository)
{
_unitOfWork = unitOfWork;
_repository = repository;
}
public virtual void Create(T entity)
{
if(entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
_repository.Add(entity);
_unitOfWork.Commit();
}
}
Example Business Logic class for the entity defined in Common Project:
public class MenuSecdLogic : EntityLogic<MenuSecd>, IMenuSecdLogic
{
IUnitOfWork _unitOfWork;
IMenuSecdRepository _repository;
public MenuSecdLogic(IUnitOfWork unitOfWork, IMenuSecdRepository repository) : base(unitOfWork, repository)
{
_unitOfWork = unitOfWork;
_repository = repository;
}
public List<MenuSecd> GetItems(string usrgrp_id)
{
return _repository.GetItems(usrgrp_id);
}
}
My Generic Repository in Data Project looks like:
public abstract class GenericRepository<T> : IGenericRepository<T> where T : class
{
protected DbContext _entities;
protected readonly IDbSet<T> _dbset;
public GenericRepository(DbContext context)
{
_entities = context;
_dbset = context.Set<T>();
}
public virtual T Add(T entity)
{
return _dbset.Add(entity);
}
public virtual T Delete(T entity)
{
return _dbset.Remove(entity);
}
public virtual void Edit(T entity)
{
_entities.Entry(entity).State = EntityState.Modified;
}
}
Repository Interface for the same Entity is defined as:
public interface IMenuSecdRepository : IGenericRepository<MenuSecd>
{
List<MenuSecd> GetItems(string usrgrp_id);
}
Repository class for above mentioned interface is:
public class MenuSecdRepository : GenericRepository<MenuSecd>, IMenuSecdRepository
{
public MenuSecdRepository(DbContext context) : base(context)
{
}
public List<MenuSecd> GetItems(string usrgrp_id)
{
return _dbset.Where(m => m.usrgrp_id == usrgrp_id).ToList();
}
}
My DbContext looks like:
public class DashboardContext : DbContext
{
public DashboardContext() : base("Name=DBEntities")
{
}
public DbSet<MenuSecd> menusecd { get; set; }
public override int SaveChanges()
{
var modifiedEntries = ChangeTracker.Entries().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);
//future custom implementation like auditing
return base.SaveChanges();
}
}
My UnitOfWork looks like:
public sealed class UnitOfWork : IUnitOfWork
{
private DbContext _dbContext;
public UnitOfWork(DbContext context)
{
_dbContext = context;
}
public int Commit()
{
return _dbContext.SaveChanges();
}
//disposes current object
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
//disposes all external resources
private void Dispose(bool disposing)
{
if (disposing)
{
if (_dbContext != null)
{
_dbContext.Dispose();
_dbContext = null;
}
}
}
}
My controller:
public class DashController : Controller
{
private readonly IMenuSecdLogic _menuSecdLogic;
public DashController(IMenuSecdLogic menuSecdLogic)
{
_menuSecdLogic = menuSecdLogic;
}
public void Save()
{
var menuSecd = new menuSecd();
//populate all fields for entity MenuSecd
_menuSecdLogic.Create(menuSecd);
}
}
My Unity Config in App_Start looks like :
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<DbContext, DashboardContext>();
container.RegisterType<IUnitOfWork, UnitOfWork>();
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<>));
container.RegisterType<IMenuSecdLogic, MenuSecdLogic>();
container.RegisterType<IMenuSecdRepository, MenuSecdRepository>();
}
So when run above project everything builds fine. But when controller calls:
_menuSecdLogic.Create(menuSecd);
It reaches Entity Logic and adds a new entity to _repository at :
_repository.Add(entity);
_unitOfWork.Commit();
But when it hits next line to actually save it to database which is :
return _dbContext.SaveChanges();
in UnitOfWork.cs file.
It comes to dashboardContext where it finally have to save it to database. But it does execute :
var modifiedEntries = ChangeTracker.Entries().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);
return base.SaveChanges();
But nothing changes in database. There will be no record in database. To test I have added modifiedEntries to see if it is in context or not. By the time control reaches this point I see no modified entries at all. But in EntityLogic.cs it does add a new entity to local entities in repository.
I am not sure what is happening with UnitOfWork here. I ran SQL Profiler to see if it is hitting database or not. Interestingly it is not hitting database at all. But if my make following changes to EntityLogic like this:
public virtual void Create(T entity)
{
if(entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
_repository.Add(entity);
_repository.Save();
//_unitOfWork.Commit();
}
It hits Database and records gets saved fine. But I am not getting why it is neither tracking changes nor hitting database if I use _unitOfWork.Commit() which I want to do. Please help.
It looks like your issue is the scope of your DbContext. Your UnitOfWork and GenericRepository<T> classes are getting different instances.
Not super familiar with Unity, but it looks like you want to use something like this for your DbContext registration:
container.RegisterType<DbContext, DashboadContext>(new PerRequestLifetimeManager());
This will create a single DashboardContext for each request, and your UnitOfWork and GenericRepository<T> classes will be working within the same context.

InvalidOperationException in EF Repository with Ninject

I make custom authentication for my ASP.NET MVC project and I use EF 6.1.3 and Ninject.MVC 3.2.1. I use repositories and unit of work patterns.
I want validate unique username at registration in my view model with custom ValidationAttribute.
Sometimes my repository throw InvalidOperationException with description:
the operation cannot be completed because the dbcontext has been disposed.
This is my Ninject configuration:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<DbContext>().To<MyPortfolioDbContext>().InRequestScope();
kernel.Bind(typeof(IDbRepository<>)).To(typeof(EfRepository<>));
kernel.Bind<Func<IUnitOfWork>>().ToMethod(ctx => () => ctx.Kernel.Get<EfUnitOfWork>());
kernel.Bind<IUnitOfWork>().To<EfUnitOfWork>();
kernel.Bind<IAuthenticationManager>().To<AuthenticationManager>();
kernel.Bind(k => k
.From("MyPortfolio.Services.Authentication", "MyPortfolio.Services.Data")
.SelectAllClasses()
.BindDefaultInterface());
}
This is my ValidationAttribute:
public class RegistrationValidator : ValidationAttribute
{
[Inject]
public IDbRepository<User> Users { get; set; }
public override bool IsValid(object value)
{
string username = (string)value;
bool result = true;
if (this.Users.FirstOrDefault(u => u.Username == username) != null)
{
result = false;
}
return result;
}
}
And this is my repository:
public class EfRepository<T> : IDbRepository<T> where T : class, IAuditInfo, IDeletableEntity
{
private IDbSet<T> dbSet;
private DbContext context;
public EfRepository(DbContext context)
{
if (context == null)
{
throw new ArgumentException("An instance of DbContext is required to use this repository.", nameof(context));
}
this.context = context;
this.dbSet = this.context.Set<T>();
}
//another methods
//the method that throw an exception
public T FirstOrDefault(Expression<Func<T, bool>> filterExpression)
{
return this.dbSet.Where(x => !x.IsDeleted).FirstOrDefault(filterExpression);
}
//another methods
}
If you need another code of my project please tell me.
My hypothesis is that on injecting the repository into ValidationAttribute, Ninject used old dbContext. What is your opinion.

how wait second operation on my context before first completes with lifestyle PerWebRequest for the context and asynchronous calls to it

My generic repository Interface is:
public interface IGenericRepository<T , TEntityKey> where T : EntityBase<TEntityKey>
{
IEnumerable<T> GetAll();
IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
T FindBy(TEntityKey entityKey);
Task<T> FindByAsync(TEntityKey entityKey);
T Add(T entity);
T Delete(T entity);
void Edit(T entity);
void Save();
void Dispose();
}
I used await for all async methods in implementing my repositories.
with using Castle Windsor as IOC container, I installed my context with PerWebRequestLifeStyle.
The client sends two requests and each request maps to different repositories implemented by IGenericRepository and this exception rises:
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
I changed life style of the context to transient but still the exception rises.
Can anyone help where I'm wrong?
GenericRepository Implementation:
public abstract class GenericRepository<T, TEntityKey> : IGenericRepository<T, TEntityKey>
where T : EntityBase<TEntityKey>
{
protected IDbContext _entities;
protected readonly IDbSet<T> _dbset;
protected GenericRepository(IDbContext context)
{
_entities = context;
_dbset = _entities.Set<T>();
}
~GenericRepository()
{
_entities.Dispose();
}
public virtual IEnumerable<T> GetAll()
{
return _dbset.AsEnumerable<T>();
}
public IEnumerable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
IEnumerable<T> query = _dbset.Where(predicate).AsEnumerable();
return query;
}
public T FindBy(TEntityKey entityKey)
{
var result = _dbset.SingleOrDefault(e => e.Id.ToString() == entityKey.ToString());
return result;
}
public Task<T> FindByAsync(TEntityKey entityKey)
{
var result = _dbset.SingleOrDefaultAsync(e => e.Id.ToString() == entityKey.ToString());
return result;
}
public virtual T Add(T entity)
{
return _dbset.Add(entity);
}
public virtual T Delete(T entity)
{
return _dbset.Remove(entity);
}
public virtual void Edit(T entity)
{
_entities.Entry(entity).State = EntityState.Modified;
}
public virtual void Save()
{
_entities.SaveChanges();
}
public async Task SaveAsync()
{
await _entities.SaveChangesAsync();
}
public void Dispose()
{
if (_entities != null)
{
_entities.Dispose();
_entities = null;
GC.SuppressFinalize(this);
}
}
}
I think you have some inherited repositories like these:
Public Repository1<Class1, KeyClass1> : GenericRepository<T, TEntityKey>
{
Public Repository1(IDbContext c) : base(c) { }
}
Public Repository2<Class2, KeyClass2> : GenericRepository<T, TEntityKey>
{
Public Repository2(IDbContext c) : base(c) { }
}
This means your Castle Windsor will create one instance for IDbContext and injects it into both repositories that causes your error.
I can suggest you to change your base class to this:
public abstract class GenericRepository<T, TEntityKey> : IGenericRepository<T, TEntityKey>
where T : EntityBase<TEntityKey>
{
protected IDbContext _entities;
protected readonly IDbSet<T> _dbset;
protected GenericRepository()
{
_entities = new MyDbContext();
_dbset = _entities.Set<T>();
}
...
}

Entity Framework read queries locking all database

I'm developing a web application using ASP.NET MVC and EF6 to access the database.
One of the features of my web application allow the user to download a Excel file. The query to get the information from the database takes like 5 seconds and I notice that until the query it's done we can't do anything on the rest of the web application.
Is this the normal behaviour of EF, lock the database even with AsNoTracking on the query?
If I'm not doing anything wrong and this is the default behaviour of EF how should I resolve this locking problem?
(Update)
I'm using a SQL Server database and the "lock" happens when for exemple I export the excel file and at the same time do a search that uses the same table.
To organize my code i'm using Repository and UnitOfWork pattern and to create the instances i'm using DI Unity.
The UnitOfWork implementation:
public class UnitOfWork : IUnitOfWork
{
private bool _disposed;
private DbContext _dbContext;
private Dictionary<string, dynamic> _repositories;
private DbContextTransaction _transaction;
public DbContext DbContext
{
get { return _dbContext; }
}
public UnitOfWork(DbContext dbContext)
{
_dbContext = dbContext;
}
public int SaveChanges()
{
return _dbContext.SaveChanges();
}
public IRepository<TEntity> Repository<TEntity>()
{
try
{
if (ServiceLocator.IsLocationProviderSet)
return ServiceLocator.Current.GetInstance<IRepository<TEntity>>();
if (_repositories == null)
_repositories = new Dictionary<string, dynamic>();
var type = typeof(TEntity).Name;
if (_repositories.ContainsKey(type))
return (IRepositoryAsync<TEntity>)_repositories[type];
var repositoryType = typeof(Repository<>);
_repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity)), this));
return _repositories[type];
}
catch(ActivationException ex)
{
throw new ActivationException(string.Format("You need to configure the implementation of the IRepository<{0}> interface.", typeof(TEntity)), ex);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~UnitOfWork()
{
Dispose(false);
}
public void Dispose(bool disposing)
{
if(!_disposed)
{
if(disposing)
{
try
{
_dbContext.Dispose();
_dbContext = null;
}
catch(ObjectDisposedException)
{
//the object has already be disposed
}
_disposed = true;
}
}
}
}
The Repository implementation:
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
private readonly IUnitOfWork _unitOfWork;
private readonly DbContext _dbContext;
private readonly DbSet<TEntity> _dbSet;
public Repository(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbContext = unitOfWork.DbContext;
_dbSet = _dbContext.Set<TEntity>();
}
#region IRepository<TEntity> implementation
public void Insert(TEntity entity)
{
_dbSet.Add(entity);
}
public void Update(TEntity entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
}
public void Delete(TEntity entity)
{
_dbSet.Remove(entity);
}
public IQueryable<TEntity> Queryable()
{
return _dbSet;
}
public IRepository<TEntity> GetRepository<TEntity>()
{
return _unitOfWork.Repository<TEntity>();
}
#endregion
}
The Unity configuration:
container.RegisterType<DbContext, DbSittiusContext>(new PerRequestLifetimeManager());
container.RegisterType<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager());
//Catalog respository register types
container.RegisterType<IRepository<Product>, Repository<Product>>();
UnityServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
To create my query have to create a extension method like this:
public static Product FindPublishedAtDateById(this IRepository<Product> repository, int id, DateTime date)
{
return repository.
Queryable().
Where(p => p.Id == id).
Where(p => p.PublishedFrom <= date && (p.PublishedTo == null || p.PublishedTo >= date)).
SingleOrDefault();
}
If you're downloading a lot of data synchronously it will make the UI freeze up on you. Consider doing this asynchronously. What are you using client side, anyway?
I'm assuming you're generating an excel file from data in the database and it's just a matter of it being enough data that it takes ~5 seconds to create the file and send it to the user.

Categories