137

我在一个名为“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 行为不应位于数据层,而应位于管理层。所以我想把这个类移到 MyProject.Admin。

但是,如果我这样做,功能就会丢失。

我的基本问题是:我可以在不同的项目中有 2 个部分类,但都指的是同一个“类”吗?

如果没有,有没有办法在不将数据层逻辑与 UI 逻辑混合的情况下完成我想要做的事情?

4

9 回答 9

191

不,您不能在两个不同的程序集(项目)中有两个部分类引用同一个类。一旦程序集被编译,元数据就会被烘焙,你的类不再是部分的。部分类允许您将同一类的定义拆分为两个文件。

于 2009-03-15T07:53:16.263 回答
15

如前所述,部分类是编译时现象,而不是运行时。根据定义,程序集中的类是完整的。

在 MVC 术语中,您希望将视图代码与模型代码分开,同时根据模型属性启用某些类型的 UI。查看Martin Fowler 对不同风格的 MVC、MVP 等的精彩概述:您会发现大量的设计理念。我想你也可以使用依赖注入来告诉 UI 什么样的控件对单个实体和属性是可行的。

你分离关注点的目标是伟大的。但是部分类旨在解决完全不同的问题(主要是代码生成和设计时建模语言)。

于 2009-03-15T08:46:50.440 回答
8

扩展方法和 ViewModel 是在前端扩展数据层对象的标准方法,如下所示:

数据层(类库,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;} }
  }
}

控制器 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)
于 2013-08-01T11:31:31.813 回答
2

将基础文件作为链接文件添加到您的项目中。它仍然是部分的,但它允许您在两个项目之间共享它,使它们保持同步,同时在部分类中具有特定于版本/框架的代码。

于 2011-08-24T16:40:30.870 回答
1

我也有类似的问题。我将部分类保存在我的数据项目中,所以在你的情况下是“MyProject.Data”。MetaDataClasses 不应该进入您的 Admin 项目,否则您将创建循环引用。

我为我的 MetaDataClasses 添加了一个新的 Class Lib 项目,例如“MyProject.MetaData”,然后从我的数据项目中引用它

于 2011-06-24T11:18:28.127 回答
1

也许使用静态扩展类。

于 2012-01-11T13:43:54.880 回答
1

只需在新项目中添加类文件作为链接,并在部分类中保持相同的命名空间。

于 2012-02-03T22:36:11.003 回答
0

我可能在这里弄错了,但您能不能简单地在您的 MyProject.Admin 项目中定义 ProjectMetaData 类?

于 2009-11-23T13:58:58.777 回答
0

自 2019 年以来,您可以使用技巧在不同的程序集中拥有部分类的 2 个部分。此技巧在本文中进行了解释和演示:

https://www.notion.so/vapolia/Secret-feature-Xamarin-Forms-control-s-auto-registration-1fd6f1b0d98d4aabb2defa0eb14961fa

它在其核心使用对 SDK 类项目的 MSBuild.Sdk.Extras 扩展,通过使用具有多个同时目标的一个项目,有效地在一次编译中创建多个程序集,从而解决了将类的所有部分部分放在同一个程序集中的限制同一个项目的。

于 2020-05-20T10:28:33.553 回答