我看过ninject、structuremap和其他依赖注入和服务定位器框架,但这个问题更多的是关于学习它是如何工作的,以及什么可以更好。更重要的是,我不感兴趣的是查看框架的源代码进行依赖项注入,而是了解它是如何在实践/代码中从头到尾实现的。
下面的代码是针对一个小的内部项目的,因此请记住让我开始。
这是我将域模型返回到控制器的接口。我已经决定,由于项目的大小(小),控制器的单一接口是可以接受的。
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)
{
}
}
创建了我自己的控制器工厂,允许我将模型工厂注入控制器。
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;
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;
}
}
最后添加代码,将concrete类注入工厂,注入到创建的控制器中。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new DIControllerFactory(new LinqSqlModelFactory()));
}
我唯一没有探索过的领域(我认为我现在不感兴趣)是创建一个
web.config
用于动态创建
ModelFactory
. 这是可行的,但如果我完全错过了船,靠近了,或者我在现场,我会感兴趣吗?