¿Es posible tener dos clases parciales en diferentes conjuntos que representen la misma clase?

Tengo una clase llamada ‘Artículo’ en un proyecto llamado ‘MyProject.Data’, que actúa como la capa de datos para mi aplicación web.

Tengo un proyecto separado llamado ‘MyProject.Admin’, que es un sistema de administración basado en la web para ver / editar los datos, y se creó usando ASP.NET Dynamic Data.

Básicamente quiero extender la clase de artículo, usando una clase parcial, de modo que pueda boost una de sus propiedades con un extensor “UIHint”, que me permitirá reemplazar el cuadro de texto multilínea normal con un control FCKEdit.

Mi clase parcial y extensor se vería así:

[MetadataType(typeof(ProjectMetaData))] public partial class Project { } public class ProjectMetaData { [UIHint("FCKeditor")] public object ItemDetails { get; set; } } 

Ahora todo esto funciona bien si la clase parcial está en el mismo proyecto que la clase parcial original, es decir, el proyecto MyProject.Data.

Pero el comportamiento de la interfaz de usuario no debería estar en la capa de datos, sino en la capa de administración. Así que quiero mover esta clase a MyProject.Admin.

Sin embargo, si hago eso, la funcionalidad se pierde.

Mi pregunta fundamental es: ¿puedo tener 2 clases parciales en proyectos separados, pero ambas se refieren a la misma “clase”?

Si no, ¿hay alguna manera de lograr lo que estoy tratando de hacer sin mezclar la lógica de la capa de datos con la lógica de la interfaz de usuario?

No, no puede tener dos clases parciales que se refieran a la misma clase en dos conjuntos diferentes (proyectos). Una vez que se comstack el ensamblado, los metadatos se preparan y las clases ya no son parciales. Las clases parciales le permiten dividir la definición de la misma clase en dos archivos.

Como se indicó, las clases parciales son un fenómeno de tiempo de comstackción, no de tiempo de ejecución. Las clases en ensambles son por definición completas.

En términos de MVC, desea mantener el código de vista separado del código del modelo, pero habilitar ciertos tipos de IU en función de las propiedades del modelo. Eche un vistazo a la excelente visión general de Martin Fowler de los diferentes sabores de MVC, MVP y demás: encontrará ideas de diseño en abundancia. Supongo que también podría usar Dependency Injection para decirle a la UI qué tipo de controles son viables para entidades y atributos individuales.

Tu objective de separar las preocupaciones es genial; pero las clases parciales tenían la intención de abordar cuestiones completamente diferentes (principalmente con la generación de código y lenguajes de modelado de tiempo de diseño).

Los métodos de extensión y ViewModels son la forma estándar de extender objetos de capa de datos en la interfaz de esta manera:

Capa de datos (biblioteca de clases, Person.cs):

 namespace MyProject.Data.BusinessObjects { public class Person { public string Name {get; set;} public string Surname {get; set;} public string Details {get; set;} } } 

Capa de visualización (aplicación 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 + " " + person.Surname); } } } 

ViewModel (para datos extendidos específicos de vista):

 using Data.BusinessObjects namespace MyProject.Admin.ViewModels { public static class PersonViewModel { public Person Data {get; set;} public Dictionary MetaData {get; set;} [UIHint("FCKeditor")] public object PersonDetails { get { return Data.Details; } set {Data.Details = value;} } } } 

Controlador PersonController.cs:

 public ActionMethod Person(int id) { var model = new PersonViewModel(); model.Data = MyDataProvider.GetPersonById(id); model.MetaData = MyDataProvider.GetPersonMetaData(id); return View(model); } 

Ver, Person.cshtml:

 @using MyProject.Admin.Extensions 

@Model.Data.GetFormattedName()

  • @Model.MetaData["comments"]
  • @Model.MetaData["employer_comments"]
@Html.EditorFor(m => m.PersonDetails)

Agregue el archivo base como un archivo vinculado a sus proyectos. Todavía es parcial, pero le permite compartirlo entre ambos proyectos, mantenerlos sincronizados y al mismo tiempo tener un código específico de versión / marco en las clases parciales.

He tenido problemas similares con esto. Mantuve mis clases parciales en mi proyecto de datos, así que en tu caso, ‘MyProject.Data’. MetaDataClasses no debería ir en su proyecto de administración ya que creará referencias circulares de otra manera.

Agregué un nuevo proyecto de Class Lib para mis MetaDataClasses, por ejemplo, ‘MyProject.MetaData’ y luego hice referencia a esto desde mi proyecto de datos.

Tal vez use una clase de extensión estática.

Puede que me equivoque aquí, ¿pero no podría simplemente definir la clase ProjectMetaData en su proyecto MyProject.Admin?

Simplemente agregue el archivo de clase como enlace en su nuevo proyecto y mantenga el mismo espacio de nombre en su clase parcial.