Farklı montajlardaki iki kısmi sınıfın aynı sınıfı temsil etmesi mümkün müdür?


128

Web uygulamam için veri katmanı görevi gören 'MyProject.Data' adlı bir projede 'Article' adlı bir sınıfım var.

Verileri görüntülemek / düzenlemek için web tabanlı bir yönetim sistemi olan 'MyProject.Admin' adlı ayrı bir projem var ve ASP.NET Dinamik Verileri kullanılarak oluşturulmuş.

Temel olarak Makale sınıfını kısmi bir sınıf kullanarak genişletmek istiyorum, böylece özelliklerinden birini bir "UIHint" genişletici ile genişletebilirim, bu da normal çok satırlı metin kutusunu FCKEdit denetimiyle değiştirmeme izin verir.

Kısmi sınıfım ve genişleticim şöyle görünür:

[MetadataType(typeof(ProjectMetaData))]
public partial class Project
{
}

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

Şimdi, eğer kısmi sınıf orijinal kısmi sınıfla aynı projedeyse, yani MyProject.Data projesindeyse bunların hepsi iyi çalışıyor.

Ancak kullanıcı arayüzü davranışı Veri katmanında değil, Yönetici katmanında yer almalıdır. Bu yüzden bu sınıfı MyProject.Admin'e taşımak istiyorum.

Ancak, bunu yaparsam işlevsellik kaybolur.

Temel sorum şu: Ayrı projelerde 2 kısmi sınıfım olabilir, ancak her ikisi de aynı "sınıfa" atıfta bulunur mu?

Değilse, veri katmanı mantığını UI mantığıyla karıştırmadan yapmaya çalıştığım şeyi başarmanın bir yolu var mı?


1
MetadataType kavramının kötü olmasının nedeni budur. ( en.wikipedia.org/wiki/Code_smell ). Tamamen kusurlu bir çözüm - Modeli özellikle denetleyiciden görünümden ayıran MVC'yi oluşturmaya çalışıyorsunuz ve veri sınıflarında görünüm ve doğrulama mantığına ihtiyacınız var. Saçma. Bu nitelikleri uygulamanın daha iyi bir yolu olmalı. Akıcı bir API veya benzeri bir şey kullanarak bir meta veri sınıfını bir veri sınıfıyla ilişkilendirebilmelisiniz. Fırında pişirilmemeli.
Jim

Diğer bazı cevaplar şundan bahseder: Mutlak bir zorunluluksa ve başvurulan derleme kaynağına sahipseniz, kaynak modelleri her zaman bağlantılı dosyalar olarak ekleyebilirsiniz (Varolan Öğe Ekle dosya seçicide bölme düğmesi), böylece bunlar, montaj ref yerine tüketen (Model / Veri katmanınızı WCF aracılığıyla bir Hizmet Referansı ile ifşa etmeye ve bu kısmi kod oluşturulmuş sınıfları genişletmeye benzer bir strateji.) Asla katmanları parçalamak zorunda kalmazsınız - her zaman alt sınıf yapabilirsiniz. Ve MetadataTypeModelleri daha çok ViewModels gibi yapar.
JoeBrockhaus

Cevap vermek için çok geç, ama burada
Usman

Cevap vermek için çok geç olduğunu biliyorum ama burada bir çözüm sundum.
Usman

Yanıtlar:


178

Hayır, iki farklı derlemede (projede) aynı sınıfa başvuran iki kısmi sınıfınız olamaz. Derleme derlendikten sonra, meta veriler eklenir ve sınıflarınız artık kısmi değildir. Kısmi sınıflar, aynı sınıfın tanımını iki dosyaya bölmenize izin verir.


15

Belirtildiği gibi, kısmi sınıflar çalışma zamanı değil, derleme zamanı olgusudur. Derlemelerde sınıflar tanım gereği tamamlanmıştır.

MVC terimlerinde, görünüm kodunu model kodundan ayrı tutmak, ancak model özelliklerine bağlı olarak belirli UI türlerini etkinleştirmek istiyorsunuz. Martin Fowler'ın MVC, MVP ve diğerlerinin farklı tatlarına ilişkin mükemmel genel bakışına bir göz atın : birçok tasarım fikri bulacaksınız. Kullanıcı arayüzüne bireysel varlıklar ve öznitelikler için ne tür kontrollerin uygun olduğunu söylemek için Bağımlılık Enjeksiyonunu da kullanabileceğinizi düşünüyorum .

Endişeleri ayırma amacınız harika; ancak kısmi sınıfların tamamen farklı sorunları ele alması amaçlanmıştır (öncelikle kod oluşturma ve tasarım zamanı modelleme dilleriyle).


8

Uzantı yöntemleri ve ViewModels, ön uçtaki veri katmanı nesnelerini şu şekilde genişletmenin standart yoludur:

Veri Katmanı (sınıf kitaplığı, Person.cs):

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

Görüntü Katmanı (web uygulaması) 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 (genişletilmiş görünüme özgü veriler için):

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

Controller 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/image_@(Model.MetaData["image"]).png" >
<ul>
  <li>@Model.MetaData["comments"]</li>
  <li>@Model.MetaData["employer_comments"]</li>
</ul>
@Html.EditorFor(m => m.PersonDetails)

Extensions yorumu oldukça mantıklıdır, bu bir arabirim kullanılarak Person nesnesinden tamamen ayrıştırılabilir. Bunu sevdim!
Pale Ale

2

Temel dosyayı bağlantılı dosya olarak projelerinize ekleyin. Hala kısmi, ancak bunu her iki proje arasında paylaşmanıza, onları senkronize etmenize ve aynı zamanda kısmi sınıflarda sürüme / çerçeveye özgü koda sahip olmanıza izin verdiği için.


1

Bununla benzer sorunlar yaşadım. Kısmi sınıflarımı Veri projemde tuttum, yani sizin durumunuzda 'Projem.Data'. Başka bir şekilde dairesel referanslar oluşturacağınız için MetaDataClasses Admin projenize girmemelidir.

MetaDataClass'larım için yeni bir Class Lib projesi ekledim, örneğin 'MyProject.MetaData' ve ardından bunu Data projemden referans aldım


1

Belki statik bir uzantı sınıfı kullanın.


İyi bir fikir. Cevabınızda yeterli işlevselliği sağlayacağını düşündüğünüz şeylere bir örnek verebilir misiniz?
pvanhouten

0

Burada yanılıyor olabilirim, ancak MyProject.Admin projenizde ProjectMetaData sınıfını basitçe tanımlayamaz mısınız?


0

Sınıf dosyasını yeni projenize bağlantı olarak ekleyin ve kısmi sınıfınızda aynı ad alanını koruyun.


0

2019'dan beri, bir hile kullanarak farklı montajlarda bir kısmi sınıfın 2 parçasına sahip olabilirsiniz. Bu numara, bu makalede açıklanmış ve gösterilmiştir:

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

Özünde, SDK benzeri projelere MSBuild.Sdk.Extras uzantısını kullanır; bu, bir sınıfın tüm kısmi parçalarının aynı derlemede bulunması sınırlamasını, birden çok eşzamanlı hedefle tek bir proje kullanarak, tek bir derlemede birden çok derlemeyi etkin bir şekilde oluşturarak çözer. aynı projenin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.