Blogs

Gary's Blog

XAF – Domain Components V2010 Vol 1

     

In this post we’ll take a quick look at the upcoming technology preview for Domain Components, which will ship with 10.1. The “What’s New” file for this technology preview provides the following elevator pitch:

“The Domain Components Technology provides an elegant and intuitive way to create reusable modules. Now you can compose an application from reusable blocks abstracted from a particular persistence layer.

With the Domain Components Technology you basically define interfaces instead of declaring regular business classes. Then you specify the logic that defines how interface members behave. After that you can reuse and combine these interfaces to quickly create required domain components. The actual business classes are automatically generated by XAF at runtime.”

So the purpose of the DC technology, then, is to allow developers to produce reusable domain libraries that are abstracted from a particular persistence layer.

Currently, when using XAF, developers implement business classes that encapsulate domain knowledge. This has two disadvantages, firstly XAF only supports XPO as a persistence layer at this time, which means you must inherit from the XPO base classes and reference the XPO assembly. Secondly business classes cannot be combined as there is no multiple inheritance in C#. This means that developing a reusable domain library, abstracted from a persistence layer, is very challenging.

DC will remedy this by allowing a developer to define interfaces and the implementation of their members. These interfaces can then be used to compose other interfaces before, finally, you register the required interfaces with XAF, which will generate the actual business classes at runtime time.

Right, let’s have a look at a quick example. We’ll implement several domain components, let’s start with an IPerson interface:

[DomainComponent, ImageName("BO_Person")]   
public interface IPerson {
    [RuleRequiredField]
    string LastName { get; set; }
    string FirstName { get; set; }
    string FullName { get; }
    DateTime Birthday { get; set; }        
    bool Married { get; set; }        
    string SpouseName { get; set; }
}

There are a couple of things to note here, firstly that you can apply regular XAF attributes (RuleRequiredField, ImageName, etc) just like you’d do with a “normal” business class. Secondly, that the interface is decorated with the [DomainComponent] attribute, specifying that this interface describes a Domain Component. Of course, we could use this interface as is, but that’s not very practical, so let’s go ahead and add an implementation class:

[DomainLogic(typeof(IPerson))]
public class PersonLogic {
    public static string Get_FullName(IPerson person) {
        return string.Format("{0} {1}", person.FirstName, person.LastName);
    }
    public void AfterChange_Married(IPerson person) {
        if(!person.Married) person.SpouseName = "";
    }
}

The last thing I have to do, before I can use my Person object, is to register the IPerson interface with XAF, like so:

public sealed partial class MySolutionModule : ModuleBase
{
    public override void Setup(XafApplication application)
    {
        if (!XafTypesInfo.IsInitialized)
        {
            XafTypesInfo.Instance.AddEntityToGenerate("Person", typeof(IPerson));
        }
        base.Setup(application);
    }
}

Which causes XAF to generate my class for me:

Person

Now I can go on and define the IOrganiszation interface with a collection of IPerson objects:

[DomainComponent, ImageName("BO_Organization")]    
public interface IOrganization {
    string Name { get; set; }
    IList<IPerson> Staff { get; }
}

This simple declaration will automatically set up an association:

Organization

Here is an example of method implementation and initialization logic:

[DomainComponent, ImageName("BO_User")]
public interface IAccount {
    [SizeDc(8)]
    string Login { get; set; }
    [SizeDc(8)]
    string Password { get; set; }
    string GenerateString();
}
[DomainLogic(typeof(IAccount))]
public class AccountLogic {
    public static string GeneratePassword() {
        byte[] randomBytes = new byte[3];
        new RNGCryptoServiceProvider().GetBytes(randomBytes);
        return Convert.ToBase64String(randomBytes);
    }                
    public static void AfterConstruction(IAccount account) {
        account.Login = GeneratePassword();
        account.Password = GeneratePassword();
    }
}

Notice the use of the “SizeDC” attribute here. This attribute is analogous to the “Size” attribute that you will be used to decorating your current business classes with. Note also that this name is likely to change before the final version of DC ships. :-)

Account

Now that we have a number of interfaces defined, we can package them in an assembly and use it as a domain library. This means that I’d be able to create a new XAF application, reference the domain library, and define a new component this this:

[DomainComponent, NavigationItem, ImageName("BO_Contact")]
public interface ICustomer : IAccount, IOrganization {
}
public override void Setup(XafApplication application) {
    if(!XafTypesInfo.IsInitialized) { 
        XafTypesInfo.Instance.AddEntityToGenerate("Person", typeof(IPerson));
        XafTypesInfo.Instance.AddEntityToGenerate("Account", typeof(IAccount));
        XafTypesInfo.Instance.AddEntityToGenerate("Organization", typeof(IOrganization));
        XafTypesInfo.Instance.AddEntityToGenerate("Customer", typeof(ICustomer));
    }
    base.Setup(application);
}

Now I have a customer domain component which I can use:

Customer

We think the this DC technology is a real step towards simple development of reusable libraries and should make the lives of developers a lot easier, we hope you enjoy playing with the technology preview when it ships with 10.1.

Until next time, happy XAFing! :-)

Published Apr 06 2010, 11:31 AM by Gary Short (DevExpress)
Filed under: ,
Technorati tags: V2010 V1, XAF
Bookmark and Share

Comments

 

Twitter Trackbacks for XAF Sneak Peek ??? Domain Components - Gary's Blog [devexpress.com] on Topsy.com said:

Pingback from  Twitter Trackbacks for                 XAF Sneak Peek ??? Domain Components - Gary's Blog         [devexpress.com]        on Topsy.com

April 6, 2010 7:23 AM
 

Michael Proctor [DX-Squad] said:

Exciting stuff, can't wait to get my hands on 2010.1

April 6, 2010 7:32 AM
 

Nathanial Woolls - DX Squad said:

Very cool stuff guys

April 6, 2010 9:19 AM
 

Jascha said:

technology preview!!!

April 6, 2010 9:21 AM
 

Alain Bismark said:

Just amazing !!!!

April 6, 2010 11:40 AM
 

Steven Rasmussen said:

First of all... Fantastic!!!  Probably a dumb question... but is there going to be documentation in 10.1 explaining how to use this?  It appears that the 'implementation' classes follow specific patterns to define the logic for properties etc.  

Is it also possible to simply implement the interface in a class that inherits from one of the XPO or XAF base classes?  For example, suppose I have both an 'Employee' class and 'Customer' class that inherit from XPObject.  Can I implement the interface 'IAddressable' (Address info) on both the classes and be able to get an XPCollection(Of IAddressable) that would contain both entities?

Could I define an association on the 'Address' class that implements the 'IAddress' interace that contains a collection of 'IAddressable' which could be either an 'Employee' or 'Customer'?

Thanks for the sneak peak and I look forward to XAFing with this!

April 6, 2010 1:08 PM
 

Roman Eremin (DevExpress) said:

Steve:

Yes, all this will be possible, but in CTP we haven't yet tested every scenario - it may require some additional plumbing.

April 6, 2010 2:37 PM
 

XAF Sneak Peek ??? Domain Components - Gary's Blog Domain on Me said:

Pingback from  XAF Sneak Peek ??? Domain Components - Gary's Blog Domain on Me

April 6, 2010 3:39 PM
 

Matthew K said:

I'm excited to see XAF presented in WPF (or XPF). Did I miss the announcement somewhere?

April 6, 2010 8:37 PM
 

Chris Walsh [DX-Squad] said:

Matthew, that is incorrect.  XPF is merged code bases of Silverlight & WPF.  

April 6, 2010 9:02 PM
 

Tien Do said:

Very cool change and I hope to see it soon it next update.

In fact the most two things that I expected to see in XAF are interface based business object and persistent layer independent-ability, but none of them has been existed :)

Tiendq,

April 7, 2010 4:55 AM
 

Tien Do said:

One more thing, why do you put underscore in the method name such as Get_FullName(IPerson person), is it necessary? I don't think that it follows .NET convention for method name.

April 7, 2010 5:00 AM
 

Alex Boston said:

If  'implementation' classes follow specific patterns to define the logic for properties and methods"

this will result in too much pain. why not some thing like delegates?

Also in suggest  that we use term 'behavior' classes than 'implementation' classes,them providing a technique to apply/enable those 'behavior' classes statically or dynamically.

April 7, 2010 3:44 PM
 

Alex Boston said:

Roman:

BTW keep an eye on your health,As every time i see your photo i see you drinking.

April 7, 2010 3:46 PM
 

Tien Do said:

I just re-read your post and noticed that you are promoting to use static methods in business object. Yes, static methods in business objects (not helper, common...), is it necessary? how about IoC and unit testing, or mocking?

April 7, 2010 10:46 PM
 

Cafer Sadik Abalioglu Holding A.S. said:

I'm confused about physical table structure for inheritance and multiple inheritance scenarios. Will all interfaces (domain components) have their own physical table?

April 8, 2010 9:03 PM
 

Arno Harskamp said:

At first I was rather excited about Domain Components so I went ahead and in my own time set up usecase to play around with the concept by mainly building a factory class and methods without implementation, purely to get a feel for working with the concept. Unfortunately my excitement slowly dwindled as I quickly felt the lack of certain features that would otherwise be available working with instances themselves:

You'll lose the ability to hide infrastructure properties from BO properties; interfaces do not support member scope/visibility. State properties that would have to be remembered on a per-object basis would now always have to be publicly visible. Polymorphic inheritance is out the window as well.

Implementation/behaviour classes turn out to be more bulky than if one was to use class instances. I found that implementing specialty collections was/is a pain too. DC would have to support a way to tell the factory what specific collection implementation to use.

For the examples given here this method appears to be the golden hit, but having applied several mechanics we use in our businessmodel against this DC method I quickly found out that to get certain things done, there's gonna be a lot of 'backward' plumbing.

I love to give it a try against the 10.1 implementation but I am not so sure anymore I will adapt this method for our current projects. But as always, thumbs up for the great work you guys do!

April 9, 2010 5:16 AM
 

Tien Do said:

It seemed that Gary no longer posts more replies here :)

I downloaded XAF 10.1 today and to be going to play with it, there is only one unclear point here, the meaning of logic class? What is DomainLogic attribute used for, for example, IAccount and AccountLogic?

Thanks,

April 22, 2010 2:52 AM
 

Dave said:

Very cool stuff, but this all goes way over my head. I'll leave it to the professionals!

April 22, 2010 2:18 PM
 

Gary Short (DevExpress) said:

@Tien, the difference between IAccount and AccountLogic in the DC technology is pretty much the same as the difference between interfaces and implementation classes in standard C#. The interface defines the properties and methods that a class must implement if it implements the interface, whilst the class actually contains the implementation of the properties and methods defined in the interface.

The DC technology follows this pattern. The definition of an entity's properties are contained in the interface, whilst the implementation of the entity's business logic is contained in the DomainLogic class.

It's pretty intuitive actually, since interface, by design, cannot contain implementation code, were would your business logic live if not in an implementation class?

If you have any further questions, please get in touch.

April 23, 2010 10:43 AM
 

Muhammad Naeem Ijaz said:

How AfterChange_Married in PersonLogic is called or it is a event handler?.

May 2, 2010 6:46 AM
 

Dennis (DevExpress Support) said:

@Muhammad:

The AfterChange_Married is not an event handler, though it may resemble it at first glance. In this method you should define additional logic that will be called after the property value is set. BTW, there are also AfterConstruction, BeforeGet, BeforeSet, etc. "events" and this list will be possibly extended in the future.

These "events" are embedded in the corresponding order into the property or class body when it's constructed from interfaces and domain logics at runtime.

May 4, 2010 10:55 AM
 

Robin 1 said:

Where can i get full documentation on these "events" ? Help file?

July 10, 2010 12:01 PM
 

Robin 1 said:

Does Domain Component support LINQ and Stored procedures since the application model is typed now? Any documention available?

July 10, 2010 12:05 PM
More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.