2016-03-29 16 views
1

Bir arka uç hizmetiyle bağlantı kurarken bir ASP.NET MVC web sitesine sahibim. Ön ve arka uç DTO'ları iletişim kurmak için kullanır.Bu genel sınıfı nasıl uygularsınız?

public class MyDto 
{ 
    public string Name {get;set;} 
} 

web siteme kullananlara doğrudan bu DTO göstermek istemiyorum, bu yüzden aynı veriyi alan bir ViewModel yaptı.

public class MyViewModel 
{ 
    public string Name {get;set;} 
} 

Şimdi, tüm bu görüntüleme modelleri için, güncelleştirme, yayın ve diğer yöntemler aynıdır. Her bir viewmodel için aynı denetleyici eylemlerini yeniden yazmak yerine, tüm bu yöntemleri içeren bir soyut denetleyici oluşturmaya karar verdim.

public interface IViewModelControllerActions<T> 
{ 
    IUpdateData<T> UpdateData { get; } //IUpdateData defined somewhere else 
    IUploadData<T> UploadData { get; } // IUploadData defined somewhere else 
    // definitions for other actions 
} 

benim ViewModel eklendi::

public class MyViewModel : IViewModelControllerActions<MyDto> 
{ 
    public string Name {get;set;} 

    public IUpdateData<T> UpdateData { get { /* Do stuff to get UpdateData */ } } 
    public IUploadData <T> UploadData { get { /* Do stuff to get UploadData */ } } 
} 

Ve soyut denetleyicisi oluşturmak:

public abstract class ViewModelController<T>: Controller where T : IViewModelControllerActions<T> 
{ 
     [HttpPost] 
     public ActionResult Upload(T input) 
     { 
      // do stuff with T.UploadData to upload 
     } 

     [HttpPost] 
     public ActionResult Update(T input) 
     { 
      // do stuff with T.UpdateData to update 
     } 

     // other methods 
} 

tüm görünüm modelleri aynı davranışı olurdu böylece Yani bir arabirim yapılmış Buradaki fikir şudur: Yeni bir dto ve viewmodel sunulduğunda, tek yapmanız gereken benim viewmodel üzerindeki IViewModelControllerActions arayüzünü uygulamaktır:

public class MyNewCoolerViewModel : IViewModelControllerActions<MyNewCoolerDto> 
{ 
    public string Name {get;set;} 
    public string AnotherNewName {get;set;} 
    public int ANumber {get;set;} 

    public IUpdateData<T> UpdateData { get { /* Do stuff to get UpdateData */ } } 
    public IUploadData <T> UploadData { get { /* Do stuff to get UploadData */ } } 
} 

Ve soyut birinden devralan yeni bir boş denetleyicisi oluşturun:

public class MyNewCoolerController : ViewModelController<MyNewCoolerViewModel> {} 

denetleyici içindeki tüm mantık zaten uygulanacaktır diye.

tip MyNewCoolerViewModel genel tür veya yöntem ViewModelController < T> türü parametresi T olarak kullanılamaz: Ancak, bu hata mesajını alıyorum. MyNewCoolerViewModel gelen IViewModelControllerActions hiçbir örtük referans dönüşüm yoktur < MyNewCoolerViewModel>

hata mesajı anlamak, ancak, bunu düzeltmek için nasıl anlamıyorum. Bu kurulumu nasıl çalıştırabilirim?

+0

Yanıtla katılıyorum - bunun MVC mimarisi pahasına aşırı derecede karmaşık olabileceğini düşünüyorsunuz. Modeliniz güncelleme/yükleme işlemlerini gerçekleştirmemelidir. Modellerinizin ve denetleyicilerinizin iş katmanınız içinde daha basit ve karmaşıklığı yönetmesi genellikle en iyisidir. Automapper ayrıca orijinal sorununuzu çözebilir. –

+0

Bunu bir süre önce denedim ve sonunda MVC'nin jenerik denetleyici bazlarını desteklemediğini öğrendim. Belki değişti ama bir google değerinde. –

cevap

0

Automapper'a baktınız mı?

Sanırım onu ​​aşırı derecede karmaşık hale getiriyorsunuz - sorununun doğrudan bir cevabı olmadığını biliyorum, ancak DTO -> ViewModel problemi tipik olarak bir türden bir eşleştirici kullanılarak çözülür. Projenizdeki bu yaklaşımda yanlış olan nedir?

+0

Bahşiş için teşekkürler! Ancak, Automapper'ın yeni bir DTO ve VM eklendiğinde yeni bir denetleyicide Güncelleştirme, Yükleme ve diğer yöntemleri yeniden yazması sorununun nasıl çözüleceğini anlamıyorum. – ohyeah

0

Bu bir bulmaca gibi tür hissediyor, ama bir süre ona baktıktan sonra, ana konu kontrolörü T kendinden referans olmasıdır: Bu durumda T zorunda olması demektir

abstract class ViewModelController<T>: Controller where T : IViewModelControllerActions<T> 

IViewModelControllerActions<IViewModelControllerActions<T>> tipinde olmak. kontrolör bunu

kullanmak Ama dürüst olmak gerekirse, bu (IMO) MVC-mimarisi ile çok iyi uyum vermez amacına bağlı olarak, ViewModelController<T,U>:Controller where T:IViewModelController<U> veya ViewModelController<IViewModelControllerAction<T>> ya olmalıdır.denetleyici ve yeniden kullanım gelince, tamamını IViewModelControllerAction-arayüzü atlamak ve sadece temel sınıf yöntemleri, böyle bir şey geçersiz düşünüyorum:

public abstract class ViewModelController<T,U>:Controller{ public ActionResult Update(T item){...} public abstract void Save(U dto); }

U amacına bağlı olarak, isteğe bağlı olabilir için şeyleri uygulamak, ama bu bir başlangıç.

İlgili konular