Files to look at:
- MetadataObjects.cs (VB: MetadataObjects.vb)
- Program.cs (VB: Program.vb)
This example shows how to dynamically create persistent classes and properties, and to reuse XPO to store this information. The example is of a high level of complexity. Only advanced users may be interested in it, if they create a framework with XPO and allow their end-users to create or customize data objects and properties.
See Also:
How to define a persistent class at runtime
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.Xpo;
using DevExpress.Xpo.Metadata;
namespace PersistentMetadata {
[NonPersistent]
public class MyBaseObject : XPObject {
public MyBaseObject(Session session, XPClassInfo classInfo) : base(session, classInfo) { }
}
public abstract class PersistentTypeInfo : XPObject {
public PersistentTypeInfo(Session session) : base(session) { }
string _Name;
public string Name {
get { return _Name; }
set { SetPropertyValue("Name", ref _Name, value); }
}
[Association]
public XPCollection<PersistentAttributeInfo> TypeAttributes { get { return GetCollection<PersistentAttributeInfo>("TypeAttributes"); } }
protected void CreateAttributes(XPTypeInfo ti) {
foreach(PersistentAttributeInfo a in TypeAttributes) {
ti.AddAttribute(a.Create());
}
}
}
public class PersistentClassInfo : PersistentTypeInfo {
public static void FillDictionary(XPDictionary dictionary, ICollection<PersistentClassInfo> data) {
foreach(PersistentClassInfo twc in data) {
twc.CreateClass(dictionary);
}
foreach(PersistentClassInfo twc in data) {
twc.CreateMembers(dictionary);
}
}
public const string AssemblyName = "";
public PersistentClassInfo(Session session) : base(session) { }
protected virtual Type GetDefaultBaseClass() {
return typeof(MyBaseObject);
}
public XPClassInfo CreateClass(XPDictionary dictionary) {
XPClassInfo result = dictionary.QueryClassInfo(AssemblyName, Name);
if(result == null) {
XPClassInfo baseClassInfo;
if(BaseClass != null)
baseClassInfo = BaseClass.CreateClass(dictionary);
else
baseClassInfo = dictionary.GetClassInfo(GetDefaultBaseClass());
result = dictionary.CreateClass(baseClassInfo, Name);
CreateAttributes(result);
}
return result;
}
void CreateMembers(XPDictionary dictionary) {
XPClassInfo ci = dictionary.GetClassInfo(AssemblyName, Name);
foreach(PersistentMemberInfo mi in OwnMembers) {
mi.CreateMember(ci);
}
}
PersistentClassInfo _BaseClass;
public PersistentClassInfo BaseClass {
get { return _BaseClass; }
set { SetPropertyValue("BaseClass", ref _BaseClass, value); }
}
[Association]
public XPCollection<PersistentMemberInfo> OwnMembers { get { return GetCollection<PersistentMemberInfo>("OwnMembers"); } }
}
public abstract class PersistentMemberInfo : PersistentTypeInfo {
public PersistentMemberInfo(Session session) : base(session) { }
internal XPMemberInfo CreateMember(XPClassInfo owner) {
XPMemberInfo result = owner.FindMember(Name);
if(result == null)
result = CreateMemberCore(owner);
CreateAttributes(result);
return result;
}
protected abstract XPMemberInfo CreateMemberCore(XPClassInfo owner);
PersistentClassInfo _Owner;
[Association]
public PersistentClassInfo Owner {
get { return _Owner; }
set { SetPropertyValue("Owner", ref _Owner, value); }
}
}
public class PersistentReferenceMemberInfo : PersistentMemberInfo {
public PersistentReferenceMemberInfo(Session session) : base(session) { }
PersistentClassInfo _ReferenceType;
public PersistentClassInfo ReferenceType {
get { return _ReferenceType; }
set { SetPropertyValue("ReferenceType", ref _ReferenceType, value); }
}
protected override XPMemberInfo CreateMemberCore(XPClassInfo owner) {
XPMemberInfo member = owner.CreateMember(Name, ReferenceType.CreateClass(owner.Dictionary));
return member;
}
}
public class PersistentCollectionMemberInfo : PersistentMemberInfo {
public PersistentCollectionMemberInfo(Session session) : base(session) { }
protected override XPMemberInfo CreateMemberCore(XPClassInfo owner) {
return owner.CreateMember(Name, typeof(XPCollection), true);
}
}
public class PersistentCoreTypeMemberInfo : PersistentMemberInfo {
public PersistentCoreTypeMemberInfo(Session session) : base(session) { }
string _TypeName;
public string TypeName {
get { return _TypeName; }
set { SetPropertyValue("TypeName", ref _TypeName, value); }
}
protected override XPMemberInfo CreateMemberCore(XPClassInfo owner) {
return owner.CreateMember(Name, Type.GetType(TypeName, true));
}
}
public abstract class PersistentAttributeInfo : XPObject {
public PersistentAttributeInfo(Session session) : base(session) { }
public abstract Attribute Create();
PersistentTypeInfo _Owner;
[Association]
public PersistentTypeInfo Owner {
get { return _Owner; }
set { SetPropertyValue("Owner", ref _Owner, value); }
}
}
public class PersistentAssociationAttribute : PersistentAttributeInfo {
public PersistentAssociationAttribute(Session session) : base(session) { }
string _an;
public string AssociationName { get { return _an; } set { SetPropertyValue("AssociationName", ref _an, value); } }
string _ean;
public string ElementAssemblyName { get { return _ean; } set { SetPropertyValue("ElementAssemblyName", ref _ean, value); } }
string _etn;
public string ElementTypeName { get { return _etn; } set { SetPropertyValue("ElementTypeName", ref _etn, value); } }
public override Attribute Create() {
return new AssociationAttribute(AssociationName, ElementAssemblyName, ElementTypeName);
}
}
}
C#using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using DevExpress.Xpo;
using DevExpress.Xpo.Metadata;
using DevExpress.Xpo.DB;
using System.Collections;
namespace PersistentMetadata {
class Program {
static void Main(string[] args) {
new PersistentMetadataExample().Execute();
}
}
public class PersistentMetadataExample {
public void Execute() {
InitDataLayers();
CreateMetadata();
CreateDatabaseAndDefaultData();
LoadData();
}
IDataLayer metadataStorage, dataStorage;
void InitDataLayers() {
string metadataFileName = "Metadata.xml";
string dataFileName = "Data.mdb";
if(File.Exists(metadataFileName)) File.Delete(metadataFileName);
if(File.Exists(dataFileName)) File.Delete(dataFileName);
metadataStorage = XpoDefault.GetDataLayer(InMemoryDataStore.GetConnectionString(metadataFileName), AutoCreateOption.DatabaseAndSchema);
dataStorage = XpoDefault.GetDataLayer(AccessConnectionProvider.GetConnectionString(dataFileName), AutoCreateOption.DatabaseAndSchema);
}
void CreateMetadata() {
using(UnitOfWork uof = new UnitOfWork(metadataStorage)) {
PersistentClassInfo classCustomer = new PersistentClassInfo(uof);
classCustomer.Name = "Customer";
PersistentCoreTypeMemberInfo propFullName = new PersistentCoreTypeMemberInfo(uof);
propFullName.Name = "FullName";
propFullName.TypeName = typeof(string).FullName;
classCustomer.OwnMembers.Add(propFullName);
PersistentCollectionMemberInfo propOrders = new PersistentCollectionMemberInfo(uof);
propOrders.Name = "Orders";
classCustomer.OwnMembers.Add(propOrders);
PersistentAssociationAttribute attrCustomerOrders = new PersistentAssociationAttribute(uof);
attrCustomerOrders.ElementTypeName = "Order";
propOrders.TypeAttributes.Add(attrCustomerOrders);
PersistentClassInfo classOrder = new PersistentClassInfo(uof);
classOrder.Name = "Order";
PersistentCoreTypeMemberInfo propOrderDate = new PersistentCoreTypeMemberInfo(uof);
propOrderDate.Name = "OrderDate";
propOrderDate.TypeName = typeof(DateTime).FullName;
classOrder.OwnMembers.Add(propOrderDate);
PersistentReferenceMemberInfo propCustomer = new PersistentReferenceMemberInfo(uof);
propCustomer.Name = "Customer";
propCustomer.ReferenceType = classCustomer;
classOrder.OwnMembers.Add(propCustomer);
PersistentAssociationAttribute attrOrdersCustomer = new PersistentAssociationAttribute(uof);
propCustomer.TypeAttributes.Add(attrOrdersCustomer);
uof.CommitChanges();
}
}
void InitDataDictionary(UnitOfWork dataSession) {
using(UnitOfWork metadataSession = new UnitOfWork(metadataStorage)) {
XPCollection<PersistentClassInfo> classes = new XPCollection<PersistentClassInfo>(metadataSession);
PersistentClassInfo.FillDictionary(dataSession.Dictionary, classes);
}
}
readonly int OrderCount = 1;
readonly DateTime OrderDate = DateTime.Today;
void CreateDatabaseAndDefaultData() {
using(UnitOfWork dataSession = new UnitOfWork(dataStorage)) {
InitDataDictionary(dataSession);
dataSession.UpdateSchema(dataSession.GetClassInfo(null, "Customer"), dataSession.GetClassInfo(null, "Order"));
XPClassInfo classCustomer = dataSession.GetClassInfo("", "Customer");
XPBaseObject customer = (XPBaseObject)classCustomer.CreateNewObject(dataSession);
customer.SetMemberValue("FullName", "John Doe");
for(int i = 0; i < OrderCount; i++) {
XPClassInfo classOrder = dataSession.GetClassInfo("", "Order");
XPBaseObject order = (XPBaseObject)classOrder.CreateNewObject(dataSession);
order.SetMemberValue("OrderDate", OrderDate);
order.SetMemberValue("Customer", customer);
}
dataSession.CommitChanges();
}
}
void LoadData() {
using(UnitOfWork dataSession = new UnitOfWork(dataStorage)) {
InitDataDictionary(dataSession);
XPClassInfo classCustomer = dataSession.GetClassInfo("", "Customer");
XPBaseObject customer = (XPBaseObject)dataSession.FindObject(classCustomer, null);
IList orders = (IList)customer.GetMemberValue("Orders");
}
}
}
}