контейнерно-независимый подход, очевидно, использует Абстрактную Фабрику :
public interface ITheFactory
{
IThe Create(IPrincipal user);
}
Вы можете взять зависимость от ITheFactory вместо IThe:
public class TheController : Controller
{
private readonly IThe the;
public TheController(ITheFactory theFactory)
{
if (theFactory == null)
{
throw new ArgumentNullException("theFactory");
}
this.the = theFactory.Create(this.User);
}
}
Я не могу вспомнить, заполнен ли this.User
в это время, но если это не так, вы можете просто сохранить ссылку на фабрику и лениво разрешить вашу зависимость при первом запросе.
Однако, Controller.User
немного особенный, потому что он также должен быть доступен как Thread.CurrentPrincipal
. Это означает, что в этом особом случае вам на самом деле не нужно вводить абстрактную фабрику. Вместо этого вы можете написать Decorator , который выполняет выбор при каждом использовании:
public class UserSelectingThe : IThe
{
private readonly IThe the1;
private readonly IThe the2;
public UserSelectingThe(IThe the1, IThe the2)
{
if (the1 == null)
{
throw new ArgumentNullException("the1");
}
if (the2 == null)
{
throw new ArgumentNullException("the2");
}
this.the1 = the1;
this.the2 = the2;
}
// Assuming IThe defines the Foo method:
public Baz Foo(string bar)
{
if (Thread.CurrentPrincipal.IsInRole("r1"))
{
return this.the1.Foo(bar);
}
return this.the2.Foo(bar);
}
}
В этом случае вы сможете использовать исходный класс TheController без изменений.