Castle Windsor 项目中快速使用
新建项目如下:
一个模型类,一个接口,一个实现方法。我的目的很明确就是在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