J'ai une application WPF où PageItems sont des objets modèles.Comment puis-je émuler l'héritage multiple et utiliser la réflexion pour optimiser ce code?
Mon ViewModel principal a une ObservableCollection de PageItemViewModels, chacun se construisant lui-même à partir de son objet modèle PageItem correspondant.
Chaque PageItemViewModel hérite de la classe abstraite BaseViewModel afin d'obtenir la fonctionnalité INotifyPropertyChanged.
Chaque PageItemViewModel met également en œuvre le IPageItemViewModel afin de vous assurer qu'il a les propriétés nécessaires.
je vais finalement avoir environ 50 pages, donc je veux éliminer tout code inutile:
- SOLVED (voir plus bas): est-il un moyen que je peux obtenir des cours de PageItemViewModel à Hériter idcode et Titre donc je n'ai pas à les implémenter dans chaque classe? Je ne peux pas les mettre dans BaseViewModel car d'autres ViewModels en héritent et n'ont pas besoin de ces propriétés, et je ne peux pas les mettre dans IPageItemViewModel car c'est seulement une interface. Je comprends que je dois l'héritage multiple pour ce qui C# ne supporte pas
- SOLVED (voir plus bas): déclaration est-il un moyen que je peux me débarrasser du commutateur, par exemple en quelque sorte utiliser réflexion à la place?
Ci-dessous est une application autonome Console qui montre le code que j'ai dans mon application WPF:
using System.Collections.Generic;
namespace TestInstantiate838
{
public class Program
{
static void Main(string[] args)
{
List<PageItem> pageItems = PageItems.GetAll();
List<ViewModelBase> pageItemViewModels = new List<ViewModelBase>();
foreach (PageItem pageItem in pageItems)
{
switch (pageItem.IdCode)
{
case "manageCustomers":
pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
break;
case "manageEmployees":
pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
break;
default:
break;
}
}
}
}
public class PageItemManageCustomersViewModel : ViewModelBase, IPageItemViewModel
{
public string IdCode { get; set; }
public string Title { get; set; }
public PageItemManageCustomersViewModel(PageItem pageItem)
{
}
}
public class PageItemManageEmployeesViewModel : ViewModelBase, IPageItemViewModel
{
public string IdCode { get; set; }
public string Title { get; set; }
public PageItemManageEmployeesViewModel(PageItem pageItem)
{
}
}
public interface IPageItemViewModel
{
//these are the properties which every PageItemViewModel needs
string IdCode { get; set; }
string Title { get; set; }
}
public abstract class ViewModelBase
{
protected void OnPropertyChanged(string propertyName)
{
//this is the INotifyPropertyChanged method which all ViewModels need
}
}
public class PageItem
{
public string IdCode { get; set; }
public string Title { get; set; }
}
public class PageItems
{
public static List<PageItem> GetAll()
{
List<PageItem> pageItems = new List<PageItem>();
pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
return pageItems;
}
}
}
Refonte: l'interface a changé de classe abstraite
using System;
using System.Collections.Generic;
namespace TestInstantiate838
{
public class Program
{
static void Main(string[] args)
{
List<PageItem> pageItems = PageItems.GetAll();
List<ViewModelPageItemBase> pageItemViewModels = new List<ViewModelPageItemBase>();
foreach (PageItem pageItem in pageItems)
{
switch (pageItem.IdCode)
{
case "manageCustomers":
pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
break;
case "manageEmployees":
pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
break;
default:
break;
}
}
foreach (ViewModelPageItemBase pageItemViewModel in pageItemViewModels)
{
System.Console.WriteLine("{0}:{1}", pageItemViewModel.IdCode, pageItemViewModel.Title);
}
Console.ReadLine();
}
}
public class PageItemManageCustomersViewModel : ViewModelPageItemBase
{
public PageItemManageCustomersViewModel(PageItem pageItem)
{
IdCode = pageItem.IdCode;
Title = pageItem.Title;
}
}
public class PageItemManageEmployeesViewModel : ViewModelPageItemBase
{
public PageItemManageEmployeesViewModel(PageItem pageItem)
{
IdCode = pageItem.IdCode;
Title = pageItem.Title;
}
}
public abstract class ViewModelPageItemBase : ViewModelBase
{
//these are the properties which every PageItemViewModel needs
public string IdCode { get; set; }
public string Title { get; set; }
}
public abstract class ViewModelBase
{
protected void OnPropertyChanged(string propertyName)
{
//this is the INotifyPropertyChanged method which all ViewModels need
}
}
public class PageItem
{
public string IdCode { get; set; }
public string Title { get; set; }
}
public class PageItems
{
public static List<PageItem> GetAll()
{
List<PageItem> pageItems = new List<PageItem>();
pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
return pageItems;
}
}
}
Répondre à l'élimination de l'instruction Switch:
Merci Jab:
string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
string viewModelName = assemblyName + ".ViewModels.PageItem" + StringHelpers.ForcePascalNotation(pageItem.IdCode) + "ViewModel";
var type = Type.GetType(viewModelName);
var viewModel = Activator.CreateInstance(type, pageItem) as ViewModelBase;
AllPageViewModels.Add(viewModel);
c'est juste l'approche pragmatique que je cherchais, j'ai dû tweek le code un peu que j'ai posté ci-dessus, merci! –
Je suis content que tu aimes ça. Bien que je pencherais vers la solution de Mike Spross à long terme. La responsabilité est plus claire là-bas. – Jab
Je dois dire que je ne suis pas d'accord avec la réponse. C'est pragmatique sans doute, mais pas une approche très commune dans le code de production. – Groo