我在名为“MyProject.Data”的项目中有一个名为“Article”的类,它充当我的Web应用程序的数据层。
我有一个名为“MyProject.Admin”的独立项目,它是一个基于Web的管理系统,用于查看/编辑数据,并使用ASP.NET动态数据构建。
基本上我想使用部分类来扩展Article类,这样我就可以使用“UIHint”扩展器扩充其中一个属性,这将允许我用FCKEdit控件替换普通的多行文本框。
我的部分课程和扩展程序看起来像这样:
[MetadataType(typeof(ProjectMetaData))]
public partial class Project
{
}
public class ProjectMetaData
{
[UIHint("FCKeditor")]
public object ItemDetails { get; set; }
}
如果部分类与原始部分类在同一个项目中,即MyProject.Data项目,这一切都可以正常工作。
但是UI行为不应该位于数据层中,而应该位于Admin层中。所以我想把这个类移到MyProject.Admin。
但是,如果我这样做,功能就会丢失。
我的基本问题是:我可以在单独的项目中有2个部分类,但两者都指的是同一个“类”吗?
如果没有,有没有办法完成我正在尝试做的事情,而不将数据层逻辑与UI逻辑混合在一起?
答案 0 :(得分:168)
不,你不能在两个不同的程序集(项目)中引用两个部分类来引用同一个类。编译程序集后,元数据将被烘焙,您的类不再是部分数据。部分类允许您将同一类的定义拆分为两个文件。
答案 1 :(得分:13)
如上所述,部分类是编译时现象,而不是运行时。程序集中的类根据定义是完整的。
在MVC术语中,您希望将视图代码与模型代码分开,然后根据模型属性启用某些类型的UI。查看不同风格的MVC,MVP和诸如此类的Martin Fowler's excellent overview:你会发现很多设计思路。我想你也可以使用Dependency Injection来告诉用户界面哪些控件对于单个实体和属性是可行的。
分离问题的目的很棒;但是,部分类旨在解决完全不同的问题(主要是代码生成和设计时建模语言)。
答案 2 :(得分:7)
扩展方法和ViewModels是在前端扩展数据层对象的标准方法,如下所示:
数据层(类库,Person.cs):
namespace MyProject.Data.BusinessObjects
{
public class Person
{
public string Name {get; set;}
public string Surname {get; set;}
public string Details {get; set;}
}
}
显示层(Web应用程序)PersonExtensions.cs:
using Data.BusinessObjects
namespace MyProject.Admin.Extensions
{
public static class PersonExtensions
{
public static HtmlString GetFormattedName(this Person person)
{
return new HtmlString(person.Name + " <b>" + person.Surname</b>);
}
}
}
ViewModel(用于扩展视图特定数据):
using Data.BusinessObjects
namespace MyProject.Admin.ViewModels
{
public static class PersonViewModel
{
public Person Data {get; set;}
public Dictionary<string,string> MetaData {get; set;}
[UIHint("FCKeditor")]
public object PersonDetails { get { return Data.Details; } set {Data.Details = value;} }
}
}
Controller PersonController.cs:
public ActionMethod Person(int id)
{
var model = new PersonViewModel();
model.Data = MyDataProvider.GetPersonById(id);
model.MetaData = MyDataProvider.GetPersonMetaData(id);
return View(model);
}
查看,Person.cshtml:
@using MyProject.Admin.Extensions
<h1>@Model.Data.GetFormattedName()</h1>
<img src="~/Images/People/image_@(Model.MetaData["image"]).png" >
<ul>
<li>@Model.MetaData["comments"]</li>
<li>@Model.MetaData["employer_comments"]</li>
</ul>
@Html.EditorFor(m => m.PersonDetails)
答案 3 :(得分:2)
将基本文件作为链接文件添加到项目中。它仍然是部分的,但允许您在两个项目之间共享它,保持它们同步,同时在部分类中具有版本/框架特定代码。
答案 4 :(得分:1)
我遇到过类似的问题。我在我的Data项目中保留了我的部分类,所以在你的情况下是'MyProject.Data'。 MetaDataClasses不应该进入您的Admin项目,因为您将创建其他明智的循环引用。
我为MetaDataClasses添加了一个新的类Lib项目,例如'MyProject.MetaData'然后从我的数据项目中引用它
答案 5 :(得分:1)
也许使用静态扩展类。
答案 6 :(得分:0)
我可能会在这里弄错,但你不能简单地在MyProject.Admin项目中定义ProjectMetaData类吗?
答案 7 :(得分:0)
只需在新项目中将类文件添加为链接,并在分部类中保留相同的命名空间。
答案 8 :(得分:0)
自2019年以来,您可以使用技巧在不同的程序集中使用局部类的2个部分。本文将解释和演示此技巧:
它以MSBuild.Sdk.Extras扩展为类项目的SDK,通过使用具有多个同时目标的一个项目,有效地创建多个程序集,解决了将类的所有部分都放在同一程序集中的限制。在同一项目的一份汇编中。