Как создать МОК, когда ключевому классу нужна Сессия (или другая зависящая от контекста переменная)

Я пытаюсь выяснить, как использовать МОК в ситуациях, где зависимые классы могут измениться на основе некоторой переменной в приложении (в этом случае, Состояние сеанса). Например, каждый из наших клиентов имеют различную базу данных, таким образом, соединение с базой данных должно быть основано на значении, сохраненном на их Сессии (особенно, так как у некоторых пользователей могло быть несколько баз данных, если бы они владеют несколькими компаниями и переключились бы между базами данных).

Вот универсальный пример того, как мы в настоящее время настраивали эту структуру:

public class MyTestController : ControllerBase
{
    Repository _rep;

    public MyTest(Repository rep)
    {
        _rep = rep;
    }

    public MyTest()
    {
        string connString = String.Format("Server={0}; Database={1};"
            , SessionContainer.ServerName, SessionContainer.DatabaseName;
        var dc = new DataContext(connString);
        _rep = new Repository(dc);
    }

    public int SampleFn()
    {
        return _rep.GetCountOfEmployees();
    }
}

public class Repository
{
    DataContext _context;

    public Repository(DataContext context)
    {
        _context = context;
    }
} 

Мы смогли бы установить это использование МОК и устранить c-скалистые-вершины по умолчанию? Если так, как? У меня нет проблемы просто с помощью D.I. как это, но я хотел бы исследовать возможность StructureMap или Единицы (примечание: мы обычно передаем в дб/сервере классу фабрики, который создает datacontext... выше примера, только для краткости).

9
задан alexandrul 18 May 2010 в 05:59
поделиться

1 ответ

Как создается экземпляр репозитория, а также его время жизни определяется Контроллер не заботится.

Когда вы регистрируете компоненты в контейнере, вы должны указать время жизни компонента. В зависимости от вашей реализации вы можете просто выбрать установку времени жизни репозитория для отслеживания сеанса.

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

Вам определенно необходимо избавьтесь от конструктора по умолчанию.


Я не могу вспомнить, как это сделать в Unity или StructureMap, поэтому вот пример Castle Windsor.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализация

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все необходимое.

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовал стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать собственный стиль жизни PerWebSession. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

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

Вам определенно нужно избавиться от конструктора по умолчанию.


Вне моей головы. Я не могу вспомнить, как это сделать в Unity или StructureMap, поэтому вот пример Castle Windsor.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализацию

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все это

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовали стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать собственный стиль жизни PerWebSession. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

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

Вам определенно нужно избавиться от конструктора по умолчанию.


Вне моей головы. Я не могу вспомнить, как это сделать в Unity или StructureMap, поэтому вот пример Castle Windsor.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализацию

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все это

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовали стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать собственный стиль жизни PerWebSession. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

но сделайте это вне Контроллера.

Вам определенно нужно избавиться от конструктора по умолчанию.


Я не могу вспомнить, как это сделать в Unity или StructureMap, поэтому вот вам Castle Windsor пример.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализацию

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все вещи

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовал стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать собственный PerWebSession Стиль жизни. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

но сделайте это вне Контроллера.

Вам определенно нужно избавиться от конструктора по умолчанию.


Я не могу вспомнить, как это сделать в Unity или StructureMap, поэтому вот вам Castle Windsor пример.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализацию

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все вещи

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовал стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать собственный PerWebSession Стиль жизни. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

sa, пример Виндзорского замка.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализацию

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все вещи

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовал стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать индивидуальный стиль жизни PerWebSession. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

sa, пример Виндзорского замка.

Определите абстрактную фабрику:

public interface IRepositoryFactory
{
    Repository Create();
}

и реализацию

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

Теперь зарегистрируйте все

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

Здесь я использовал стиль жизни PerWebRequest, но если вы хотите оптимизировать, вы можете создать индивидуальный стиль жизни PerWebSession. Это не так сложно сделать в Castle, но я не могу вспомнить, насколько это сложно в других контейнерах DI.

Вам также потребуется зарегистрировать HttpContextBase, поскольку MyRepositoryFactory зависит от него.

15
ответ дан 4 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: