Возможно ли, чтобы два отдельных класса в разных сборках представляли один и тот же класс?
У меня есть класс под названием "Article" в проекте под названием "MyProject.Data", который действует как слой данных для моего веб-приложения.
У меня есть отдельный проект под названием MyProject.Admin, который является веб-административной системой для просмотра/редактирования данных и был создан с использованием динамических данных ASP.NET.
В принципе, я хочу расширить класс Article, используя частичный класс, чтобы я мог расширить одно из своих свойств с помощью расширителя "UIHint", который позволит мне заменить нормальное многострочное текстовое поле на элемент управления FCKEdit.
Мой частичный класс и расширитель будут выглядеть так:
[MetadataType(typeof(ProjectMetaData))]
public partial class Project
{
}
public class ProjectMetaData
{
[UIHint("FCKeditor")]
public object ItemDetails { get; set; }
}
Теперь все работает отлично, если частичный класс находится в том же проекте, что и исходный частичный класс - то есть проект MyProject.Data.
Но поведение пользовательского интерфейса не должно находиться в слое данных, а, скорее, на уровне администратора. Поэтому я хочу переместить этот класс в MyProject.Admin.
Однако, если я это сделаю, функциональность будет потеряна.
Мой основной вопрос: могу ли я иметь 2 частичных класса в отдельных проектах, но оба относятся к одному и тому же "классу"?
Если нет, есть ли способ выполнить то, что я пытаюсь сделать, не смешивая логику уровня данных с логикой пользовательского интерфейса?
Ответы
Ответ 1
Нет, у вас не может быть двух частичных классов, относящихся к одному и тому же классу в двух разных сборках (проектах). После сборки сборки метаданные запихиваются, а ваши классы уже не являются частичными. Частичные классы позволяют разбить определение одного и того же класса на два файла.
Ответ 2
Как отмечалось, частичные классы - это явление времени компиляции, а не время выполнения. Классы в сборках по определению полные.
В условиях MVC вы хотите сохранить код просмотра отдельно от кода модели, но включите определенные типы пользовательского интерфейса на основе свойств модели. Посмотрите Мартин Фаулер отличный обзор различных вкусов MVC, MVP и еще чего-то: вы найдете идеи дизайна в изобилии. Я полагаю, вы также можете использовать Injection of Dependency, чтобы сообщить пользовательскому интерфейсу, какие элементы управления жизнеспособны для отдельных объектов и атрибутов.
Ваша цель отделить заботы велика; но частичные классы предназначались для решения совершенно разных проблем (в первую очередь с использованием языков генерации кода и моделирования времени разработки).
Ответ 3
Методы расширения и 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;}
}
}
Уровень отображения (веб-приложение) 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);
}
View, Person.cshtml:
@using MyProject.Admin.Extensions
<h1>@Model.Data.GetFormattedName()</h1>
<img src="~/Images/People/[email protected](Model.MetaData["image"]).png" >
<ul>
<li>@Model.MetaData["comments"]</li>
<li>@Model.MetaData["employer_comments"]</li>
</ul>
@Html.EditorFor(m => m.PersonDetails)
Ответ 4
Добавьте базовый файл в качестве связанного файла в свои проекты. Он по-прежнему частичный, но как позволяет вам делиться ими между обоими проектами, сохранять их синхронизированными и в то же время иметь код версии/рамки в частичных классах.
Ответ 5
У меня были схожие проблемы. Я сохранил свои частичные классы в проекте Data, поэтому в вашем случае "MyProject.Data". MetaDataClasses не должны входить в ваш проект Admin, так как вы создадите круговые ссылки, другие мудрые.
Я добавил новый класс Lib для моего MetaDataClasses, например. 'MyProject.MetaData', а затем ссылается на это из моего проекта Datap >
Ответ 6
Возможно, используйте статический класс расширения.
Ответ 7
Просто добавьте файл класса в качестве ссылки в свой новый проект и сохраните одно и то же пространство имен в своем частичном классе.
Ответ 8
Я могу ошибаться здесь, но не могли бы вы просто определить класс ProjectMetaData в проекте MyProject.Admin?