137

「MyProject.Data」というプロジェクトに「Article」というクラスがあり、Web アプリケーションのデータ層として機能します。

「MyProject.Admin」という別のプロジェクトがあります。これは、データを表示/編集するための Web ベースの管理システムであり、ASP.NET 動的データを使用して構築されました。

基本的に、部分クラスを使用して Article クラスを拡張し、そのプロパティの 1 つを「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

いいえ、2 つの異なるアセンブリ (プロジェクト) で同じクラスを参照する 2 つの部分クラスを持つことはできません。アセンブリがコンパイルされると、メタデータが組み込まれ、クラスは部分的ではなくなります。部分クラスを使用すると、同じクラスの定義を 2 つのファイルに分割できます。

于 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 に答える
1

新しいプロジェクトにリンクとしてクラスファイルを追加し、部分クラスで同じ名前空間を維持するだけです。

于 2012-02-03T22:36:11.003 に答える
1

これについても同様の問題がありました。私は部分クラスをデータプロジェクトに保持したので、あなたの場合は「MyProject.Data」です。そうしないと循環参照が作成されるため、MetaDataClasses を Admin プロジェクトに含めないでください。

「MyProject.MetaData」などの MetaDataClasses に新しい Class Lib プロジェクトを追加し、これをデータ プロジェクトから参照しました。

于 2011-06-24T11:18:28.127 に答える
1

おそらく、静的拡張クラスを使用してください。

于 2012-01-11T13:43:54.880 に答える
0

ここで間違っているかもしれませんが、MyProject.Admin プロジェクトで ProjectMetaData クラスを単純に定義することはできませんか?

于 2009-11-23T13:58:58.777 に答える