我必須承認,我是ASP.Net MVC的新手,我目前正在研究如何開始我的新項目的所有最佳實踐。到目前爲止,我已經理解了存儲庫模式和工作單元的概念,並且我已經進入了依賴注入和控制反轉(IoC)。在過去的2天裏我一直在研究這個問題,並且我總結出有2個我喜歡的IoC容器,它們是StructureMap和NInject,儘管這兩個容器都不是完美的,我還沒有設法讓StructureMap工作,儘管我喜歡光重量語法。IoC容器跨越ASP.Net MVC Newb
這是我的應用程序的構建方式。首先,我有我的數據上下文和存儲庫中的以下接口:
public interface IDataContext : IDisposable
{
IRepository<T> Repository<T>() where T : class;
void Commit();
}
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
IEnumerable<T> Find(Expression<Func<T, bool>> where);
T Single(Expression<Func<T, bool>> where);
void Insert(T entity);
void Delete(T entity);
}
然後我對此有LinqToSql實現像這樣:
public class LinqToSqlDataContext : IDataContext
{
private readonly DataContext _context;
public LinqToSqlDataContext(DataContext context)
{
_context = context;
}
public IRepository<T> Repository<T>() where T : class
{
return new LinqToSqlRepository<T>(_context);
}
public void Commit()
{
_context.SubmitChanges();
}
public void Dispose()
{
}
}
public class LinqToSqlRepository<T> : IRepository<T> where T : class
{
private readonly DataContext _context;
public LinqToSqlRepository(DataContext context)
{
_context = context;
}
public IEnumerable<T> GetAll()
{
return _context.GetTable<T>();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> where)
{
return _context.GetTable<T>().Where(where);
}
public T Single(Expression<Func<T, bool>> where)
{
return _context.GetTable<T>().SingleOrDefault(where);
}
public void Insert(T entity)
{
_context.GetTable<T>().InsertOnSubmit(entity);
}
public void Delete(T entity)
{
_context.GetTable<T>().DeleteOnSubmit(entity);
}
}
目前我已經找到了2個地方,我需要用我的數據上下文。
- 內的控制器構造
- 在數據標註屬性(不能有一個構造函數)
我試圖刪除任何依賴關係,盡我的能力。請說你是否有任何建議。
現在到我的IoC容器實現。首先NInject我設法修改我的Global.asax.cs文件到以下幾點:
public class MvcApplication : NinjectHttpApplication
{
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel(new ServiceModule());
// Gives my wrapper class access to the kernel instance
IoCContainer.Initialize(kernel);
return kernel;
}
public static void RegisterRoutes(RouteCollection routes)
{
...
}
}
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IDataContext>().To<LinqToSqlDataContext>().InRequestScope();
Bind<DataContext>().To<MyDataContext>().InRequestScope();
}
}
public static class IoCContainer
{
private static IKernel _kernel;
public static void Initialize(IKernel kernel)
{
_kernel = kernel;
}
public static T Get<T>()
{
return _kernel.Get<T>();
}
public static object Get(Type type)
{
return _kernel.Get(type);
}
}
這工作得很好。該控制器構造函數現在自動他們之間的依賴有線起來,我的數據註釋中屬性我可以說:
var context = IoCContainer.Get<IDataContext>();
我喜歡NInject但即使有文件的Global.asax.cs從NinjectHttpApplication繼承(其中處理很多管道的)我仍然覺得我很想去除很多事情。
接下來我看了一下StructureMap。 StructureMap沒有自帶內置的ControllerFactory,但生成一個非常簡單。我在測試時將其放在我的Global.asax.cs文件中。說
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
// Configure structure map
ObjectFactory.Initialize(x =>
{
x.For<IDataContext>()
.HttpContextScoped()
.Use<LinqToSqlDataContext>();
x.For<DataContext>()
.HttpContextScoped()
.Use<MyDataContext>();
});
}
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
public static void RegisterRoutes(RouteCollection routes)
{
...
}
}
public class StructureMapControllerFactory : DefaultControllerFactory
{
public override IController CreateController(RequestContext requestContext, string controllerName)
{
try
{
var controllerType = base.GetControllerType(requestContext, controllerName);
return ObjectFactory.GetInstance(controllerType) as IController;
}
catch (Exception e)
{
return base.CreateController(requestContext, controllerName);
}
}
}
我也應該能夠得到一個實例,以我的數據註解屬性中的數據方面:下面是該文件的最終內容
var context = ObjectFactory.GetInstance<IDataContext>();
這肯定感覺在語法上很多打火機對我來說。但是,當我運行我的應用程序不起作用。
我想知道以下幾點:
- 無論我的模式是正確的。
- 哪個IoC容器是最好最容易使用的。如果NInject然後我正確地做這個,如果StructureMap那麼我怎麼能修復我收到的錯誤。
我知道這是很多,但我真的很感激,如果有人可以幫忙。謝謝。
*更少*如果你想要一個答案... – 2010-07-22 19:09:27
你必須做很多事情 - 使用IDataContext,IRepository,當你實際上只需要一個接口來定義方法和一個實現它的類。你不必把所有東西都捆起來,大約2到3次。在Ninject網站的源代碼中查看使用Ninject實現的DI。 Nate Kohari在他的GitHub上有它。 – mare 2010-07-22 23:29:46