Я смотрел на платформы Ninject, StructureMap и Other Dependency Injection и Service Locator, но этот вопрос больше касается изучения того, как это работает и что может быть лучше. Более того, мне не интересно смотреть на исходный код Framework для внедрения зависимостей, но я понимаю, как это достигается от начала до конца на практике / в коде.
Приведенный ниже код предназначен для небольшого внутреннего проекта, поэтому с учетом этого позвольте мне начать.
Вот мой интерфейс для возврата доменных моделей на мои контроллеры. Я решил, что из-за размера проекта (маленького) приемлем был единый интерфейс для контроллеров.
interface IModelFactory
{
IEnumerable<User> GetUsers();
User GetUser(Guid UserID);
bool Add(User User);
bool Delete(User User);
bool Update(User User);
IEnumerable<Car> GetCars();
Car GetCar(Guid CarID);
bool Add(Car Car);
bool Delete(Car Car);
bool Update(Car Car);
}
Каждый контроллер имеет наследство от DIBaseController
, поэтому мне не нужно было создавать закрытые члены для каждого контроллера.
public abstract class DIBaseController : Controller
{
protected IModelFactory ModelFactory { get; set; }
public DIBaseController(IModelFactory ModelFactory)
{
this.ModelFactory = ModelFactory;
}
}
public class HomeController : DIBaseController
{
public HomeController (IModelFactory ModelFactory)
: base(ModelFactory)
{
}
}
Создал мою собственную фабрику контроллеров, которая позволяет мне внедрять мой ModelFactory в контроллеры.
internal class DIControllerFactory : DefaultControllerFactory
{
private IModelFactory _ModelFactory;
internal DIControllerFactory(IModelFactory ModelFactory)
{
this._ModelFactory = ModelFactory;
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
IController result = null;
string thisnamespace = this.GetType().Namespace;
//This could be improved I bet.
Type controller = Type.GetType(thisnamespace.Substring(0, thisnamespace.IndexOf('.')) + ".Controllers." + controllerName + "Controller");
if (controller != null
&& controller.IsSubclassOf(typeof(DIBaseController)))
{
result = (IController)Activator.CreateInstance(controller, new object[] { this._ModelFactory });
}
else
{
result = base.CreateController(requestContext, controllerName);
}
return result;
}
}
И, наконец, добавил код для добавления класса Concreate в Factory для добавления в созданные контроллеры.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new DIControllerFactory(new LinqSqlModelFactory()));
}
Единственная область, которую я не исследовал (и я не думаю, что в данный момент мне это интересно) - это создание раздела web.config
для динамического создания ModelFactory
. Это работает, но мне интересно, если я полностью пропустил лодку, подойду ближе, или если я на месте?