【发布时间】:2010-11-27 08:08:55
【问题描述】:
我看过 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;
//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,注入到创建的Controllers中。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new DIControllerFactory(new LinqSqlModelFactory()));
}
我没有探索的唯一领域(我认为我目前不感兴趣)是创建一个web.config 部分来动态创建ModelFactory。这行得通,但如果我完全错过了船,靠近,或者如果我在现场,我很感兴趣?
【问题讨论】:
标签: asp.net-mvc-2 dependency-injection