Search This Blog

Friday, June 26, 2015

Creating associations between XPO data models in code using the XafTypesInfo API



Prerequisites:
See my About XAF Types Info Subsystem... blog post before reading.

What's New in this regard?
Just wanted to inform you guys that starting with v15.1.4, you can use the solution described in the eXpressApp Framework > Concepts > Business Model Design > Types Info Subsystem > Customize Business Object's Metadata > Create Associations in Code article for that purpose:

The following snippet illustrates how to declare an association between two class' properties when you have no access to these classes code and cannot apply the AssociationAttribute directly.

C#
ITypeInfo typeInfo1 = typesInfo.FindTypeInfo(typeof(DomainObject1));
ITypeInfo typeInfo2 = typesInfo.FindTypeInfo(typeof(DomainObject2));
IMemberInfo memberInfo1 = typeInfo1.FindMember("Object2");
IMemberInfo memberInfo2 = typeInfo2.FindMember("Object1s");
if(memberInfo1 == null) {
    memberInfo1 = typeInfo1.CreateMember("Object2"
        typeof(DomainObject2)
    );
    memberInfo1.AddAttribute(
        new DevExpress.Xpo.AssociationAttribute("A"
        typeof(DomainObject2)), true
    );
}
if(memberInfo2 == null) {
    memberInfo2 = typeInfo2.CreateMember("Object1s"
        typeof(XPCollection<DomainObject1>)
    );
    memberInfo2.AddAttribute(
        new DevExpress.Xpo.AssociationAttribute("A"
        typeof(DomainObject1)), true
    );
    memberInfo2.AddAttribute(
        new DevExpress.Xpo.AggregatedAttribute(), true
    );
}
((XafMemberInfo)memberInfo1).Refresh();
((XafMemberInfo)memberInfo2).Refresh();


As you can see in the code above, the IMemberInfo.AddAttribute method's second parameter is true. In this case, Types Info will not reload information from XPDictionary immediatelly. After adding all required attributes, call the XafMamberInfo.Refresh method for each updated member. Alternatively, you can call XafTypesInfo.RefreshInfo for each type containing updated members:


XafTypesInfo.Instance.RefreshInfo(typeof(DomainObject1));
XafTypesInfo.Instance.RefreshInfo(typeof(DomainObject2));


For XAF versions older than 15.1.4 you cannot dynamically establish an association between two persistent classes via the XafTypesInfo API. Instead, you can do this using the XPO's XPDictionary API as shown in the E250: How to customize an XPO business model at runtime example. I hope you will find this small unification helpful.

2 comments: