我应该为 DAL 和服务 类 使用单例吗?
Should I use singleton for DAL and Service classes?
我的dal和服务class如下。我使用 Ninject 来注入依赖项。
public interface IEntityRepository<T> where T : class, IEntity, new()
{
ICollection<T> GetAll(Expression<Func<T, bool>> filter = null);
T Get(Expression<Func<T, bool>> filter);
T Add(T entity);
T Update(T entity);
void Delete(T entity);
}
public class EfEntityRepositoryBase<TEntity, TContext> : IEntityRepository<TEntity>
where TEntity : class, IEntity, new()
where TContext : DbContext, new()
{
public virtual ICollection<TEntity> GetAll(Expression<Func<TEntity, bool>> filter = null)
{
using (var context = new TContext())
{
return (filter == null ? context.Set<TEntity>() : context.Set<TEntity>().Where(filter)).ToList();
}
}
public virtual TEntity Get(Expression<Func<TEntity, bool>> filter)
{
using (var context = new TContext())
{
return context.Set<TEntity>().SingleOrDefault(filter);
}
}
public virtual TEntity Add(TEntity entity)
{
using (var context = new TContext())
{
var addedEntity = context.Entry(entity);
addedEntity.State = EntityState.Added;
context.SaveChanges();
return entity;
}
}
public virtual TEntity Update(TEntity entity)
{
using (var context = new TContext())
{
var updatedEntity = context.Entry(entity);
updatedEntity.State = EntityState.Modified;
context.SaveChanges();
return entity;
}
}
public virtual void Delete(TEntity entity)
{
using (var context = new TContext())
{
var deletedEntity = context.Entry(entity);
deletedEntity.State = EntityState.Deleted;
context.SaveChanges();
}
}
}
public interface ICallService
{
}
public class CallManager : ICallService
{
}
public interface ICallDal : IEntityRepository<Call>
{
}
public class EfCallDal : EfEntityRepositoryBase<Call, DatabaseContext>, ICallDal
{
}
public class BusinessModule : NinjectModule
{
public override void Load()
{
Bind<ICallService>().To<CallManager>().InSingletonScope();
Bind<ICallDal>().To<EfCallDal>();
}
}
在 dal 和 service classes 中使用 Singleton Scope 有什么优点或缺点?根据您的经验使用它是否正确?
我也很好奇 DbContext 的依赖注入 class。
Bind<DbContext>().To<MyContext>().InSingletonScope();
我认为将单例用于上下文 class 是有风险的。不是吗?
What are the advantages or disadvantages of using Singleton Scope in
dal and service classes?
优点:
- 您只实例化一个对象,获得 CPU 和内存。
- 您可以共享状态(如果不受控制,这将是一个巨大的缺点)
缺点:
- 对象图必须是线程安全的(DbContext 不是这种情况)
- 对象图中的对象必须是无状态的,除非您希望状态被所有对象共享
在实践中,这不是一个好主意,它会成为问题的根源。
由于您似乎处于 Web 上下文中 (Asp.Net MVC),因此您应该绑定大部分对象 InRequestScope.
避免使用 new DbContext
。您的上下文应该作为构造函数参数进行绑定和注入。否则你就错过了依赖注入的重点。
一旦您了解了作用域的机制,您将能够使用单例和作用域工厂等。
我的dal和服务class如下。我使用 Ninject 来注入依赖项。
public interface IEntityRepository<T> where T : class, IEntity, new()
{
ICollection<T> GetAll(Expression<Func<T, bool>> filter = null);
T Get(Expression<Func<T, bool>> filter);
T Add(T entity);
T Update(T entity);
void Delete(T entity);
}
public class EfEntityRepositoryBase<TEntity, TContext> : IEntityRepository<TEntity>
where TEntity : class, IEntity, new()
where TContext : DbContext, new()
{
public virtual ICollection<TEntity> GetAll(Expression<Func<TEntity, bool>> filter = null)
{
using (var context = new TContext())
{
return (filter == null ? context.Set<TEntity>() : context.Set<TEntity>().Where(filter)).ToList();
}
}
public virtual TEntity Get(Expression<Func<TEntity, bool>> filter)
{
using (var context = new TContext())
{
return context.Set<TEntity>().SingleOrDefault(filter);
}
}
public virtual TEntity Add(TEntity entity)
{
using (var context = new TContext())
{
var addedEntity = context.Entry(entity);
addedEntity.State = EntityState.Added;
context.SaveChanges();
return entity;
}
}
public virtual TEntity Update(TEntity entity)
{
using (var context = new TContext())
{
var updatedEntity = context.Entry(entity);
updatedEntity.State = EntityState.Modified;
context.SaveChanges();
return entity;
}
}
public virtual void Delete(TEntity entity)
{
using (var context = new TContext())
{
var deletedEntity = context.Entry(entity);
deletedEntity.State = EntityState.Deleted;
context.SaveChanges();
}
}
}
public interface ICallService
{
}
public class CallManager : ICallService
{
}
public interface ICallDal : IEntityRepository<Call>
{
}
public class EfCallDal : EfEntityRepositoryBase<Call, DatabaseContext>, ICallDal
{
}
public class BusinessModule : NinjectModule
{
public override void Load()
{
Bind<ICallService>().To<CallManager>().InSingletonScope();
Bind<ICallDal>().To<EfCallDal>();
}
}
在 dal 和 service classes 中使用 Singleton Scope 有什么优点或缺点?根据您的经验使用它是否正确?
我也很好奇 DbContext 的依赖注入 class。
Bind<DbContext>().To<MyContext>().InSingletonScope();
我认为将单例用于上下文 class 是有风险的。不是吗?
What are the advantages or disadvantages of using Singleton Scope in dal and service classes?
优点:
- 您只实例化一个对象,获得 CPU 和内存。
- 您可以共享状态(如果不受控制,这将是一个巨大的缺点)
缺点:
- 对象图必须是线程安全的(DbContext 不是这种情况)
- 对象图中的对象必须是无状态的,除非您希望状态被所有对象共享
在实践中,这不是一个好主意,它会成为问题的根源。
由于您似乎处于 Web 上下文中 (Asp.Net MVC),因此您应该绑定大部分对象 InRequestScope.
避免使用 new DbContext
。您的上下文应该作为构造函数参数进行绑定和注入。否则你就错过了依赖注入的重点。
一旦您了解了作用域的机制,您将能够使用单例和作用域工厂等。