新建項目如下:
一個模型類,一個接口,一個實現方法。我的目的很明確就是在UI層通過Castle 調用數據訪問層的方法。
添加項目引用
CastleDemo.DataAccess 引用 CastleDemo.Domain
CastleDemo.WebUI 引用 CastleDemo.Domain(不需要引用CastleDemo.DataAccess)
安裝組件
CastleDemo.DataAccess和 CastleDemo.Domain 都需安裝 Castle.Core , Castle.Windsor
CastleDemo.DataAccess 安裝 EntityFramework
CastleDemo.Domain
IRepository:
1 public interface IRepository<T> where T : class 2 { 3 /// <summary> 4 /// 查詢 5 /// </summary> 6 /// <param name="condition">查詢條件</param> 7 /// <param name="order">排序條件</param> 8 /// <returns></returns> 9 IEnumerable<T> Find(Expression<Func<T, bool>> condition, Expression<Func<T, object>> order = null); 10 }
Product:
1 public class Product 2 { 3 public string productId { get; set; } 4 5 public string productName { get; set; } 6 }
IoCContainer:
1 internal class IoCContainer 2 { 3 private static readonly object syncRoot = new object(); 4 5 private IoCContainer() { } 6 7 private static IWindsorContainer _Instance; 8 9 public static IWindsorContainer Instance 10 { 11 get 12 { 13 lock (syncRoot) 14 { 15 if (_Instance == null) 16 { 17 _Instance = new WindsorContainer().Install(Configuration.FromAppConfig()); 18 } 19 return _Instance; 20 } 21 } 22 } 23 }
Factories:
1 public class Factories 2 { 3 public static T Repository<T>() where T : class 4 { 5 return IoCContainer.Instance.Resolve<T>(); 6 } 7 }
CastleDemo.DataAccess
BaseRepository:
1 public class BaseRepository<T> : IRepository<T> where T : class 2 { 3 private castledemoContext context = Factories.Repository<castledemoContext>(); 4 5 public IEnumerable<T> Find(Expression<Func<T, bool>> condition, Expression<Func<T,object>> order = null) 6 { 7 if (order == null) 8 { 9 return context.Set<T>().Where(condition); 10 } 11 12 return context.Set<T>().Where(condition).OrderByDescending(order); 13 } 14 }
IocInstaller:
1 public class IoCInstaller : IWindsorInstaller 2 { 3 public void Install(IWindsorContainer container, IConfigurationStore store) 4 { 5 container.Register(Component.For<castledemoContext>().LifeStyle.PerWebRequest); 6 7 container.Register(Classes.FromThisAssembly() 8 .InNamespace("CastleDemo.DataAccess.RepositoryImpl", true) 9 .LifestylePerWebRequest() 10 .WithService.AllInterfaces()); 11 } 12 }
CastleDemo.WebUI
HomeController >> Index:
1 public ActionResult Index() 2 { 3 Expression<Func<Product, bool>> condition = m => m.productName.Contains("產品"); 4 Expression<Func<Product, object>> order = m => m.productId; 5 6 var products = Factories.Repository<IRepository<Product>>().Find( order: order,condition: condition); 7 8 return View(products); 9 }
Web.config里還需在相應的地方添加一些配置:
<configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,Castle.Windsor" /> </configSections> --分割-- <httpModules> <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" /> </httpModules> --分割-- <castle> <installers> <install type="CastleDemo.DataAccess.IoCInstaller,CastleDemo.DataAccess" /> </installers> </castle>
在運行代碼前,我們還差最后一步,在前面的添加引用的時候WebUI層沒有添加對CastleDemo.DataAccess層的引用,那么這個時候我們需要把CastleDemo.DataAccess層的EntityFramework.dll 和 CastleDemo.DataAccess.dll拷貝到WebUI的BIN里面,但又有個問題來了,那我們每次對CastleDemo.DataAccess層代碼的改動都要重新拷貝,多麻煩啊,解決方法請參考我的另一篇文章 VS XCOPY
最后運行看下效果:
下載:CastleDemo
參考Windsor Tutorial:
http://docs.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx