asp.net-mvc – 在ASP.NET MVC3项目中编写多态对象
我的问题的本质是如何用MVC3和Ninject以合理的方式组合这些对象(见下文)(尽管我不确定DI应该在解决方案中发挥作用).我无法透露我的项目的真实细节,但这是一个近似,说明了问题/问题.在VB或C#中的答案表示赞赏!
我有几种不同的产品,具有各种各样的特性,但它们都需要在目录中表示.每个产品类在我的数据库中都有一个对应的表.商品具有一些特定于商品的属性,因此拥有自己的表.我已经为目录条目定义了一个接口,其目的是调用DescriptionText属性将根据底层的具体类型给出非常不同的结果. Public Class Clothing Property Identity as Int64 Property AvailableSizes As List(Of String) Property AvailableColor As List(Of String) End Class Public Class Fasteners Property Identity as Int64 Property AvailableSizes As List(Of String) Property AvailableFinishes As List(Of String) Property IsMetric As Boolean End Class Public Interface ICatalogEntry Property ProductId as Int64 Property PublishedOn As DateTime Property DescriptionText As String End Interface 鉴于DescriptionText是表示层关注的问题,我不想在我的产品类中实现ICatalogEntry接口.相反,我想将其委托给某种格式化程序. Public Interface ICatalogEntryFormatter Property DescriptionText As String End Interface Public Class ClothingCatalogEntryFormatter Implements ICatalogEntryFormatter Property DescriptionText As String End Class Public Class FastenerCatalogEntryFormatter Implements ICatalogEntryFormatter Property DescriptionText As String End Class 在一个控制器的某个地方会有这样的代码: Dim entries As List(Of ICatalogEntry) = catalogService.CurrentCatalog(DateTime.Now) 在某个地方的视图中会有这样的代码: <ul> @For Each entry As ICatalogEntry In Model.Catalog @<li>@entry.DescriptionText</li> Next </ul> 所以问题是构造函数是什么样的?如何设置它以便在适当的位置实例化适当的对象.看起来像仿制药或DI可能有助于此,但我似乎有一个心理障碍.我想出的唯一想法是将一个ProductType属性添加到ICatalogEntry,然后实现这样的工厂: Public Class CatalogEntryFactory Public Function Create(catEntry as ICatalogEntry) As ICatalogEntry Select Case catEntry.ProductType Case "Clothing" Dim clothingProduct = clothingService.Get(catEntry.ProductId) Dim clothingEntry = New ClothingCatalogEntry(clothingProduct) Return result Case "Fastener" Dim fastenerProduct = fastenerService.Get(catEntry.ProductId) Dim fastenerEntry = New FastenerCatalogEntry(fastenerProduct) fastenerEntry.Formatter = New FastenerCatalogEntryFormatter Return fastenerEntry ... End Function End Class Public ClothingCatalogEntry Public Sub New (product As ClothingProduct) Me.Formatter = New ClothingCatalogEntryFormatter(product) End Sub Property DescriptionText As String Get Return Me.Formatter.DescriptionText End Get End Property End Class ...FastenerCatalogEntry is omitted but you get the idea... Public Class CatalogService Public Function CurrentCatalog(currentDate as DateTime) Dim theCatalog As List(Of ICatalogEntry) = Me.repository.GetCatalog(currentDate) Dim theResult As New List(Of ICatalogEntry) For Each entry As ICataLogEntry In theCatalog theResult.Add(factory.Create(entry)) Next Return theResult End Function End Class 恕我直言,除了必须为每个新产品类别更改工厂外,我并没有真正得到这些代码的任何气味.然而,我的直觉说这是旧的做事方式,而现在DI和/或仿制药可以更好地做到这一点.关于如何处理这个问题的建议非常感谢(关于更好标题的建议……) 解决方法
我喜欢在视图的模型上使用默认构造函数,并通过
Automapper填充它们.
我会有一个像这样的视图模型: public interface IHasDescription { public string DescriptionText { get; set; } } public class ViewModelType : IHasDescription { [DisplayName("This will be rendered in the view")] public string SomeText { get; set; } public string DescriptionText { get; set; } } 我有一个来自DAL的模型,如下所示: public class DALModelType { public string SomeText { get; set; } } 所以你在控制器中有这样的东西: var dalModel = someRepository.GetAll(); var viewModel = Mapper.Map<DALModelType,ViewModelType>(dalModel); 并且您在某个文件中具有Automapper设置代码.这样,您只能在一个地方而不是多个方法/控制器中使用转换代码.你有一个custom resolver使用依赖注入(而不是()=>新的CustomResolver()),这将包含你获取显示文本的逻辑. Mapper.CreateMap<IHasDescription,ViewModelType>() .ForMember(dest => dest.DescriptionText,opt => opt.ResolveUsing<CustomResolver>().ConstructedBy(() => new CustomResolver())); 不确定这是否适用于您的工作流程,但它应该能够为您提供所需的内容. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-3 – 使用存储过程(MSSQL)时Dapper的
- asp.net-mvc – 使用数字属性的MVC3 DataAnnotat
- asp.net-mvc-5 – 使用Hangfire时出现SQL Server
- asp.net – MVC3 Partial View需要一个控制器,但
- asp.net – 选择性地将CSS应用于gridview中的一行
- asp.net-web-api – 在WebApi2项目中使用CacheOu
- asp.net页面生命周期
- asp.net – 部分查看并将数据传递给布局MVC3
- asp.net-mvc-3 – MVC 3 Webgrid使整行可点击
- asp.net-mvc – 使用MVC3剃刀的ASP.Net图表控件