Winforms DbContext в форме - PullRequest
       70

Winforms DbContext в форме

0 голосов
/ 27 апреля 2018

Я работаю над приложением WindowsForms. Я использую репозиторий, UoW, DI и EntityFramework. В таких приложениях рекомендуется использовать DbContext для каждой формы Windows.

Моя проблема в том, что когда я разрешаю форму IoC, в нее добавляются мои бизнес-сервисы. Это должно по умолчанию создать новый экземпляр DbContext, что нормально. Когда я открываю подформу из той же формы, хотя в эту подформу вводятся новые бизнес-сервисы, используется тот же экземпляр DbContext.

Даже если я открываю новую форму, используется тот же экземпляр DbContext, если только я не освобождаю разрешенную форму.

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

Ниже приведена краткая реализация кода, который я использую. Я включил важные части.

UnitOfWork:

    public class UnitOfWork : IUnitOfWork
{
    private DbContextBase context = null;

    /// <summary>
    /// Constructer
    /// </summary>
    public UnitOfWork(DbContextBase context)
    {
        this.context = context;
    }

    /// <summary>
    /// Gets current context.
    /// </summary>
    public DbContextBase UoWContext
    {
        get { return context; }
    }
}

UnitOfWorkManager:

    public class UnitOfWorkManager
{
    private static IUnitOfWork _unitOfWork { set; get; }

    private UnitOfWorkManager()
    {
    }

    public static IUnitOfWork Current
    {
        get
        {
            if (_unitOfWork != null)
                return _unitOfWork;
            else
            {
                _unitOfWork = Create();
                return _unitOfWork;
            }
        }
        set
        {
            _unitOfWork = value;
        }
    }

    private static IUnitOfWork Create()
    {
        return IoCManager.IoC.Resolve<IUnitOfWork>();
    }
}

Repository:

    public class Repository<TEntity, TKey> : IRepository<TEntity, TKey>
    where TEntity : class
{
    public Repository()
    {
    }

    private DbContextBase Context
    {
        get
        {
            return UnitOfWorkManager.Current.UoWContext;
        }
    }

    private DbSet<TEntity> DbSet
    {
        get
        {
            return Context.Set<TEntity>();
        }
    }
}

Бизнес-сервис:

{
public class BusinessService<TEntity, TKey> : IBusinessService<TEntity, TKey>
    where TEntity : IEntity
{
    protected IRepository<TEntity, TKey> _repository;

    public BusinessService(IRepository<TEntity, TKey> repository)
    {
        _repository = repository;
    }
}

DI Регистрация с использованием Castle-Windsor:

IoCManager.IoC.Register<DbContextBase, PMDbContext>(IoCLifeStyle.Transient);
IoCManager.IoC.Register<IEFUnitOfWork, EFUnitOfWork>(IoCLifeStyle.Transient);
IoCManager.IoC.Register<IRepository>(typeof(IRepository).Assembly, IoCLifeStyle.Transient);
IoCManager.IoC.Register<BusinessServiceInterceptor>(IoCLifeStyle.Singelton);
IoCManager.IoC.Register<IBusinessService, BusinessServiceInterceptor>(typeof(IBusinessService).Assembly, IoCLifeStyle.Transient, typeof(BusinessServiceInterceptor));
//Forms
IoCManager.IoC.Register<frm_Main>(PM.Common.Enums.IoCLifeStyle.Transient);
IoCManager.IoC.Register<frm_Calander>(PM.Common.Enums.IoCLifeStyle.Transient);
IoCManager.IoC.Register<frm_Calanders>(PM.Common.Enums.IoCLifeStyle.Transient);

1 Ответ

0 голосов
/ 28 апреля 2018

Вы должны немного изменить свой дизайн:

public class Repository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : class
{
    private readonly IUnitOfWork _unitOfWork;

    public Repository(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    private DbContextBase Context
    {
        get
        {
            return _unitOfWork.UoWContext;
        }
    }

    private DbSet<TEntity> DbSet
    {
        get
        {
            return Context.Set<TEntity>();
        }
    }
}

Тогда всякий раз, когда запрашивается новая форма

  • вводится новая услуга
  • , который получает новый репозиторий
  • который получает новый unitOfWork
  • , который получает новый dbContext

Каждый вызов службы в одной и той же форме приведет к вызову одного и того же базового -service -> repository -> unitOfWork -> context.

Если у вас есть больше услуг в форме, которые должны использовать тот же экземпляр uow:

Container.Register(Component.For<IUnitOfWork>()
    .ImplementedBy<UnitOfWork>()
    .LifestyleBoundToNearest<frmBase>());

(https://github.com/castleproject/Windsor/blob/master/docs/lifestyles.md)

Тогда uow и его контекст будут ограничены только ближайшей формой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...