Должен ли я использовать синглтон для классов DAL и Service? - PullRequest
1 голос
/ 18 января 2020

Мой даль и класс обслуживания следующие. Я использую 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>();
    }
}

Каковы преимущества или недостатки использования Singleton Scope в dal и классах обслуживания? Правильно ли будет использовать его в соответствии с вашим опытом?

Мне также любопытно узнать о внедрении зависимостей класса DbContext.

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

Я думаю, что использование синглтона для класса контекста рискованно. Не так ли?

1 Ответ

0 голосов
/ 20 января 2020

Каковы преимущества или недостатки использования Singleton Scope в dal и классах обслуживания?

Преимущества:

  • Вы создаете только один объект, получаете в Процессор и память.
  • Вы можете поделиться состоянием (что было бы огромным неудобством, если бы не контролировать)

Недостатки:

  • граф объектов должен быть потокобезопасным (это не случай DbContext)
  • объекты в графе объектов должны быть без состояния, если только вы не хотите, чтобы состояние было общим для всех ваших объектов

На практике это не очень хорошо идея, и это будет большой источник проблем.

Как вы, кажется, находитесь в веб-контексте (Asp. Net MVC), вы должны связать большинство своих объектов InRequestScope .

Избегайте использования new DbContext. Ваш контекст должен быть связан и введен как аргумент конструктора. В противном случае вы пропустите точку внедрения зависимости.

Как только вы поймете механику определения объема, вы сможете играть с синглетонами, фабриками с областями действия и т. П.

...