다른 어셈블리에서 두 개의 부분 클래스가 동일한 클래스를 나타낼 수 있습니까?


128

내 웹 응용 프로그램의 데이터 계층 역할을하는 'MyProject.Data'라는 프로젝트에 'Article'이라는 클래스가 있습니다.

데이터를 보거나 편집하기위한 웹 기반 관리 시스템 인 'MyProject.Admin'이라는 별도의 프로젝트가 있으며 ASP.NET Dynamic Data를 사용하여 빌드되었습니다.

기본적으로 부분 클래스를 사용하여 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으로 옮기고 싶습니다.

그러나 그렇게하면 기능이 손실됩니다.

내 근본적인 질문은 : 별도의 프로젝트에서 두 개의 부분 클래스를 가질 수 있지만 둘 다 동일한 "클래스"를 참조 할 수 있습니까?

그렇지 않은 경우 데이터 계층 논리와 UI 논리를 혼합하지 않고 내가하려는 일을 수행 할 수있는 방법이 있습니까?


1
이것이 바로 MetadataType의 개념이 악취가 나는 이유입니다. ( en.wikipedia.org/wiki/Code_smell ). 완전히 결함이있는 솔루션입니다-컨트롤러에서 모델과보기를 특별히 분리하는 MVC를 작성하려고하는데 데이터 클래스의보기 및 유효성 검사 논리가 필요합니다. 우스운. 이러한 속성을 적용하는 더 좋은 방법이 있어야합니다. 유창한 API 또는 이와 유사한 것을 사용하여 메타 데이터 클래스를 데이터 클래스와 연관시킬 수 있어야합니다. 구워서는 안된다.
Jim

다른 답변은 이것을 언급합니다 : 절대적이어야하고 참조 된 어셈블리 소스를 소유하고 있다면 항상 소스 모델을 링크 된 파일 (Add-Existing-Item 파일 선택기의 분리 버튼)로 포함 할 수 있습니다. 어셈블리 참조 대신 소비. (서비스 참조를 통해 WCF를 통해 모델 / 데이터 계층을 노출하고 부분 코드 생성 클래스를 확장하는 유사한 전략) 계층을 강제로 강요하지 않아도됩니다. 언제든지 하위 클래스를 만들 수 있습니다. 그리고 MetadataType모델을 ViewModel과 비슷하게 만듭니다.
JoeBrockhaus

응답하기에는 너무 늦었지만 여기
Usman

응답하기에는 너무 늦었지만 여기 에 해결책을 제시했습니다.
Usman

답변:


178

아니요, 두 개의 다른 어셈블리 (프로젝트)에서 동일한 클래스를 참조하는 두 개의 부분 클래스를 가질 수 없습니다. 어셈블리가 컴파일되면 메타 데이터가 구워지고 클래스가 더 이상 부분적이지 않습니다. 부분 클래스를 사용하면 동일한 클래스의 정의를 두 개의 파일로 분할 할 수 있습니다.


15

언급 한 바와 같이 부분 클래스는 컴파일 타임 현상이며 런타임이 아닙니다. 어셈블리의 클래스는 정의상 완전합니다.

MVC 용어에서는 뷰 코드를 모델 코드와 별도로 유지하면서 모델 속성을 기반으로 특정 종류의 UI를 사용하려고합니다. MVC, MVP 및 다양한 기능에 대한 Martin Fowler의 뛰어난 개요 를 확인하십시오 . 디자인 아이디어가 풍부하다는 것을 알 수 있습니다. Dependency Injection 을 사용 하여 UI에 개별 엔터티 및 특성에 대해 어떤 종류의 컨트롤을 사용할 수 있는지 알려줄 수 있다고 가정 합니다.

우려를 분리하려는 당신의 목표는 위대합니다. 그러나 부분 클래스는 완전히 다른 문제 (주로 코드 생성 및 디자인 타임 모델링 언어)를 해결하기위한 것입니다.


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;}
  }
}

표시 계층 (웹 응용 프로그램) 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)

Extensions 주석은 상당히 의미가 있습니다. 인터페이스를 사용하여 Person 객체와 완전히 분리 할 수 ​​있습니다. 나는 그것을 좋아한다!
창백한 Ale

2

기본 파일을 프로젝트에 링크 된 파일로 추가하십시오. 여전히 부분적이지만 두 프로젝트간에 공유하고 동기화 된 상태로 유지하면서 동시에 부분 클래스의 버전 / 프레임 워크 특정 코드를 가질 수 있습니다.


1

나는 이것과 비슷한 문제를 겪었다. 귀하의 경우에는 'MyProject.Data'이므로 부분 클래스를 데이터 프로젝트에 보관했습니다. MetaDataClasses는 관리 프로젝트에 들어 가지 않아야합니다. 다른 방법으로 순환 참조를 만들 것입니다.

내 MetaDataClasses (예 : 'MyProject.MetaData')에 새 Class Lib 프로젝트를 추가 한 후 내 데이터 프로젝트에서이 클래스를 참조했습니다.


1

아마도 정적 확장 클래스를 사용하십시오.


좋은 생각. 답변에 충분한 기능을 제공한다고 생각하는 예를 제공 할 수 있습니까?
pvanhouten

0

여기에 착각했을 수도 있지만 MyProject.Admin 프로젝트에서 ProjectMetaData 클래스를 간단하게 정의 할 수 없습니까?


0

새 프로젝트에서 클래스 파일을 링크로 추가하고 부분 클래스에서 동일한 네임 스페이스를 유지하십시오.


0

2019 이후 트릭을 사용하여 다른 어셈블리에서 부분 클래스의 두 부분을 가질 수 있습니다. 이 요령은이 기사에서 설명하고 설명합니다.

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

MSBuild.Sdk.Extras 확장 프로그램을 SDK와 같은 핵심 프로젝트로 사용하여 하나의 프로젝트에서 여러 개의 동시 대상을 사용하여 하나의 컴파일로 여러 어셈블리를 효과적으로 생성함으로써 동일한 어셈블리에 클래스의 모든 부분 부분을 갖는 제한을 해결합니다. 같은 프로젝트의.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.