Я пытаюсь выяснить, как использовать МОК в ситуациях, где зависимые классы могут измениться на основе некоторой переменной в приложении (в этом случае, Состояние сеанса). Например, каждый из наших клиентов имеют различную базу данных, таким образом, соединение с базой данных должно быть основано на значении, сохраненном на их Сессии (особенно, так как у некоторых пользователей могло быть несколько баз данных, если бы они владеют несколькими компаниями и переключились бы между базами данных).
Вот универсальный пример того, как мы в настоящее время настраивали эту структуру:
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... выше примера, только для краткости).
Как создается экземпляр репозитория, а также его время жизни определяется Контроллер не заботится.
Когда вы регистрируете компоненты в контейнере, вы должны указать время жизни компонента. В зависимости от вашей реализации вы можете просто выбрать установку времени жизни репозитория для отслеживания сеанса.
В любом случае вы можете использовать фабрику для создания репозитория из сеанса, но делать это извне Контроллера.
Вам определенно необходимо избавьтесь от конструктора по умолчанию.
Я не могу вспомнить, как это сделать в 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 зависит от него.