dimanche 29 mars 2015

Use custom property attribute to map value to another type

I"m trying to put together an abstract class that various models in my MVVM will derive from. Part of this is for abstracting IEditableObject/IChangeTracking details.


For my IEditableObject, I want to store a shallow copy of "core data" (a struct that defines data that will be serialized, typically for database storage) so that it can be cancelled or committed. What I don't want to do is type this out for each new Model that I come up with.


I've defined a [DataCoreItem] custom attribute that I thought to use on the derived class's applicable properties. For some unrelated reasons, the abstract class takes a generic DataCoreType and IDType:



public abstract class ModelObject<DataCoreType, IDType> : INotifyPropertyChanged, IEditableObject
{

public abstract DataCoreType Load(IDType id);
public abstract bool Save(DataCoreType dataCore);
public abstract bool Delete(IDType id);
// etc...


Here's an example for my CompanyModel the data core:



public struct CompanyDataCore
{
public int? ID;
public string Code;
public string Name;
public string PrimaryWebsite;
public string PrimaryPhone;
public string PrimaryEmail;
}


the derived class:



public class CompanyModel : ModelObject<CompanyDataCore, int> {

CompanyDataCore dataCore;

[DataCoreMember]
public int? ID { get { return dataCore.ID; } set { SetProperty(ref dataCore.ID, value); } }
[DataCoreMember]
public string Name { get { return dataCore.Name; } set {SetProperty(ref dataCore.Name, value); } }
[DataCoreMember]
public string Code { get { return dataCore.Code; } set { SetProperty(ref dataCore.Code, value); } }
[DataCoreMember]
public string PrimaryPhone { get { return dataCore.PrimaryPhone; } set {SetProperty(ref dataCore.PrimaryPhone, value); } }
[DataCoreMember]
public string PrimaryEmail { get { return dataCore.PrimaryEmail; } set { SetProperty(ref dataCore.PrimaryEmail, value); } }
[DataCoreMember]
public string PrimaryWebsite { get { return dataCore.PrimaryWebsite; } set { SetProperty(ref dataCore.PrimaryWebsite, value); } }


Ok, finally... what I'd like for my abstract class is to use the BeginEdit(), EndEdit() and CancelEdit() methods to handle storage of a backup copy of the data core automatically. Here's how I envision it:



[DataCoreMember(MemberName="ID")]
public int? ID { get { return dataCore.ID; } set { SetProperty(ref dataCore.ID, value); } }
// etc etc


and in my abstract class:



virtual void makeBackup() {
this.dataCoreBackup = // read all [DataCoreMember] attribs and...


... map the property to which the DataCoreMember is applied to the property of the struct as specified.


I'm inexperienced with reflection (and working generic types as well for that matter), but I gather that this can be done. I've found examples (as of yet untried) for how to get a list of those properties with the attribute applied to them, but I'm unsure how to ultimately reference the DataCore's property based on that. Can anyone show me how? Much appreciated.






Aucun commentaire:

Enregistrer un commentaire