【问题标题】:Should I use singleton for DAL and Service classes?我应该对 DAL 和服务类使用单例吗?
【发布时间】:2020-05-04 20:58:10
【问题描述】:

我的 dal 和服务类如下。我使用 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 类中使用 Singleton Scope 有哪些优点或缺点?根据您的经验使用它是否正确?

我也很好奇DbContext类的依赖注入。

Bind<DbContext>().To<MyContext>().InSingletonScope();

我认为对上下文类使用单例是有风险的。不是吗?

【问题讨论】:

    标签: asp.net-mvc entity-framework singleton ninject


    【解决方案1】:

    在中使用 Singleton Scope 有哪些优点或缺点? dal 和服务类?

    优点:

    • 您只实例化一个对象,从而获得 CPU 和内存。
    • 您可以共享状态(如果不受控制,这将是一个巨大的劣势)

    缺点:

    • 对象图必须是线程安全的(DbContext 不是这种情况)
    • 对象图中的对象必须是无状态的,除非您希望所有对象共享状态

    在实践中,这不是一个好主意,而且会产生很大的问题。

    由于您似乎处于 Web 上下文 (Asp.Net MVC) 中,因此您应该绑定大部分对象 InRequestScope

    避免使用new DbContext。您的上下文应该作为构造函数参数绑定和注入。否则你会错过依赖注入的要点。

    一旦您了解了作用域的机制,您就可以使用单例、作用域工厂等。

    【讨论】:

      猜你喜欢
      • 2011-01-11
      • 2017-06-12
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多