DI .net 读书笔记
依赖注入例子
需求:
要求用WPF MVVM和Entity Framework 以及 MySql建立一个电子商务应用程序。
一般的思维方式:
- 首先我们需要建立一个数据库,其中有个Product表

2. 使用Entity Data Model Wizard生成相应的实体模型。 参考文章
http://www.codeproject.com/Tips/739164/Entity-Framework-Tutorial-for-Beginners
3. 建立领域层
interface IProductService { IEnumerable<Product> GetFeaturedProducts( bool isCustomerPreferred); }
public partial class ProductService : Ploeh.Samples.Mary.ECommerce.Domain.IProductService { private readonly CommerceObjectContext objectContext; public ProductService() { this.objectContext = new CommerceObjectContext(); } public IEnumerable<Product> GetFeaturedProducts( bool isCustomerPreferred) { var discount = isCustomerPreferred ? .95m : 1; var products = (from p in this.objectContext.Products where p.IsFeatured select p).AsEnumerable();
return from p in products select new Product { ProductId = p.ProductId, Name = p.Name, Description = p.Description, IsFeatured = p.IsFeatured, UnitPrice = p.UnitPrice * discount }; } }
// This may be a good idea to separate the code public partial class ProductService : IDisposable { #region IDisposable Members public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); }
#endregion protected virtual void Dispose(bool disposing) { if (disposing) { this.objectContext.Dispose(); } }
}
4. WPF (原文是ASP.NET MVC 3)
5. 全局,这样做的局限是一旦我要换掉 数据访问层,我就必须要改领域层和UI层的代码,引文他们都使用在数据层定义的实体类型。

正确的思维方式:
- UI 依赖于领域的定义对象,但是一般都会加一个封装,这样把依赖限制在Controller或Model,不用影响到View层。
public class ProductViewModel { public ProductViewModel() { } public ProductViewModel(DiscountedProduct product) { this.Name = product.Name; this.UnitPrice = product.UnitPrice; } public string Name { get; set; } public string SummaryText { get { return string.Format("{0} ({1:C})", this.Name, this.UnitPrice); } } public decimal UnitPrice { get; set; } }
2. 领域层提供实体和抽象给UI层使用.
public abstract class ProductRepository { public abstract IEnumerable<Product> GetFeaturedProducts(); }
Product 的定义图:

3. 数据访问层,实现领域提供的抽象,
public class SqlProductRepository : Domain.ProductRepository { private readonly CommerceObjectContext context; public SqlProductRepository(string connString) { this.context = new CommerceObjectContext(connString); } public override IEnumerable<Domain.Product> GetFeaturedProducts() { var products = (from p in this.context.Products where p.IsFeatured select p).AsEnumerable(); return from p in products select p.ToDomainProduct(); } }
4. Overview, 这样领域对象被就一套供电设备,分别提供两个插口,可以输入亦可以输出。如果要更换,输入或输出,只需提供满足插口的设备即可。

更好的思维:

在以上的基础上再多层一个Presentation Model Layer, 用来将显示与显示逻辑分开。让软件更加可测。
浙公网安备 33010602011771号