DC: One-to-many relationship

This post may be outdated. For the latest Domain Components concepts and examples refer to the current online documentation.

In the first post of the series devoted to our new domain component (DC) technology, I tried to show an interface-defined entity in a UI.

I used some IPerson component as an example:

	public enum Gender { Unknown, Male, Female }

	public interface IPerson {
		string FirstName { get; set; }
		string MiddleName { get; set; }
		string LastName { get; set; }
		string FullName { get; }
		DateTime Birthday { get; set; }
		Gender Gender { get; set; }
	}
	[DomainLogic(typeof(IPerson))]
	public class PersonLogic {
		public static string Get_FullName(IPerson self) {
			return self.FirstName + " " + self.LastName;
		}
	}

IPerson is a library interface that will be used as an entity rarely. In a real-world application, another entity is expected. For instance, it may be a Developer, the entity that implements the IPerson interface, in addition to other interfaces. Assume the Developer contains Notes. So, we add the INote and IItemWithNotes library interfaces:

	public interface IItemWithNotes {
		IList<INote> Notes { get; }
	}

	public interface INote {
		string Text { get; set; }
		IItemWithNotes Owner { get; set; }
	}

Combining these two interfaces, we get the IDeveloper interface:

	public interface IDeveloper : IPerson, IItemWithNotes{ 
	}

I change the entity registration code, which I showed in the previous post, to the following:

		public override void Setup(XafApplication application) {
			XafTypesInfo.Instance.AddEntityToGenerate("Developer", typeof(IDeveloper));
			XafTypesInfo.Instance.GenerateEntities();
			base.Setup(application);
		}

If I run my application now, it won't work. The problem is that I should map the INote interface to a real entity. Here, I have a design challenge: should XAF generate other entities for the Developer entity, or should it require that all Developer-related entities are registered manually? Currently, I think it is better to make a developer responsible for registering entities. First, it will give him direct control on what happens in the physical database. Second, our automatic logic can be wrong. So, I change the entity registration code again:

		public override void Setup(XafApplication application) {
			XafTypesInfo.Instance.AddEntityToGenerate("Developer", typeof(IDeveloper));
			XafTypesInfo.Instance.AddEntityToGenerate("Note", typeof(INote));
			XafTypesInfo.Instance.GenerateEntities();
			base.Setup(application);
		}

After I made these changes, my application works:

DC-06

Note that the FullName property is calculated properly. Remember that we declared this property with a getter only. However, we implemented the PersonLogic class that contains the Get_FullName method. When the XpoBuilder generated the implementation of the Developer object, it uses the Get_FullName method to generate the FullName property.

As you can see in the screenshot above, the "Link" and "Unlink" Actions are available (they are circled). This means that the system thinks that a Note object can be created independently. I need a way to tell the XpoBuilder that the IItemWithNotes.Notes is an aggregated collection. I want to be able to write this:

	public interface IItemWithNotes {
		[Aggregated]
		IList<INote> Notes { get; }
	}

I still can't do that. So, I've written a test that shows what I need, and now I’m waiting for the Xpo team. I'll focus on other problems with associations. Stay tuned.

Tags
19 comment(s)
Jascha

Hi Roman,

This certainly looks very interesting - and good to see the practical manifestation of the original ideas. It's going to take a while to get my head round the strengths and weaknesses of this approach. Some initial questions:

In the above example, how might you control the table mappings (as you do currently with MapInheritanceAttribute)?

Will we be able to inject DomainLogic into domain components as a form of IOC? E.g. could we create different IPersonLogic implementers and specify which one to use at runtime e.g. choice of implementer could be based on "final" interface being implemented, application configuration, database data, logged in user, client or any other pertinent factor.

Will the framework support partial interfaces?

When are the domain classes generated - at application start up, class instantiation...?

Also, I like the open evolutionary approach you are taking here - very refreshing to get us involved. Do you envisage a "beta" type program that would allow those interested parties to experience the technology as it emerges?

Thanks,

Jascha

26 September, 2008
Roman Eremin (DevExpress)

Hi Jacha,

Table mapping is an attribute of the actual entity (IPerson can be a table in one application and just a part of bigger thing in another), so everything related to actual table mapping will be specified during DC registration in XpoBuilder.

I guess  I will write about this very soon.

Yes, it will be possible to specify different implementors and very probably every generated implementation will be able to be a DI container out of the box.

Regarding partial interaces - not sure what you mean. Interface implementation is emitted at runtime, so compile time aspects of code should not make any difference here...

If we will have many request we might release a public beta. DC technology support is built into active branch of XAF - so it will be there in 2008.3, though it may be not documented yet and not completed (due to PDC in October, 2008 vol.3 release is shorter than I originally expected in our estimations).

Roman

26 September, 2008
Jascha

Hi Roman,

Quick reply!

>Regarding partial interaces - not sure what you mean. Interface implementation is emitted at runtime, so compile time aspects of code should not make any difference here...

I assumed that it would be fine - I just wanted to ensure that there would not be any issues since I currently use partial classes to achieve certain goals.

I see that Alex Hoffman is also pushing the DI potential of this approach - at this early point, it certainly seems to have a lot to offer. At what point do the domain classes get built (application start up, object instantiation or at some other point)?

Cheers,

Jascha

26 September, 2008
Roman Eremin (DevExpress)

Hi Jacha,

Domain classes are built during GenerateEntities() call. It will be placed in the  Application.Setup code after collecting modules and calling DC registration code for each module.

You will not need to call it yourself.

We might need to provide a way to generate real assembly for partial trust environmnts (where you can't emit any sophisticated code) - time will tell.

26 September, 2008
Jascha

Hi Roman,

>Domain classes are built during GenerateEntities() call. It will be placed in the  Application.Setup code after collecting modules and calling DC registration code for each module.

Ok so that limits the factors that the DI factory can consider to those that can be configured at start up. Presumably that configuration would be in the model (e.g. add a DomainLogic node to the BOModel/Class node that allows you to select a class from the available classes for each interface in the interface tree for that class)?

Another question: in the above scenario, how would you handle a new IDeveloper DomainLogic class that implements IDeveloper.Get_FullName?

Jascha

26 September, 2008
Mohsen Benkhellat

Hi Roman,

Let's say we have an interface IUser (for logon purposes), ISupplier and IResource. I have generated to entities Empoyee:IUser,IResource and Vendor:IUser,ISupplier.

My guess is that the database will contain 2 tables Employee and Vendor. Now what happens if I want a list view of all users (no matter what entity they are from)? Can I just create a collection on IUser type and load it or should I instead Load separately all entities supporting IUser?

One appraoch that would help in this would to have a table for each interface used in a generation ans in my scenario above, I would have 3 tables IUser, IResource and ISupplier and loading all users would be trivial and if I want to load an entity (like Resource) XPO would generate a SELECT/JOIN for IUser and IResource tables.

I know it is a different approach but I wanted to have your opinion on this.

Thanks for the good work,

Mohsen

26 September, 2008
Alex Hoffman

> 2008.3, though it may be not documented yet and not completed

I'm disapointed that this isn't going to make the 8.3 release as previously announced.  This news on top of workflow likely slipping into next year.

-- Alex Hoffman

expressapp.blogspot.com

26 September, 2008
Linton

"should XAF generate other entities for the Developer entity, or should it require that all Developer-related entities are registered manually?"

Yes. The XAF framework should always strive to make the developer's life easy. My domain has grown to nearly 300 objects (why should I manually generate them). If the code will not run without it as in your example, then XAF should build it automatically. However, provide an overrideable method for those who need more control.

Also, because the release date has slipped, perhaps you can implement a GUI domain component designer as well for 9.1 release.

There is also a problem with the current XAF code when using read-only properties such as "Full_Name" with ServerMode=true. Can this issue be resolved as well?

Linton

26 September, 2008
CESAR F. QüEB

Let me say that this article it's very, very interesting and useful. My disagreement resides only in the version that will contain this feature.. like Alex says... surely until next year to see this useful feature... some crew's member in vacation?.. congratulations... i want vacations too!... only that the customers does not allow it to me!!.... :(

I hope that all XAF guys take into account

your suggestions with more professionalism the next time... because that you say.. this approach was your hard job...

Regards

26 September, 2008
drew..

thus far i have not been too into IoC etc, but am willing to learn, so pardon if this is a silly question, but looking at the listed code above, how does the listing for IDeveloper ( public interface IDeveloper : IPerson, IItemWithNotes{ }  ) actually resolve back to the INotes interface? I see a Notes IList, but Notes and INote are not the same.. Is this simply not a two-way association as currently in xaf, but 1-way based on the ref in INote to the IItemWithNotes owner?  .. just trying to wrap my head around all this. And pardon my being the devil's advocate, this seems to be taking xaf into a more complicated domain (pardon the pun)..

26 September, 2008
Mark Krasnohorsky

Hi Roman,

Yes, please leave allow for manual/only entity registration.

You could always leave it as manual and later add a feature for auto generation for scenarios where the automated generation code won't foul things up.

MK

26 September, 2008
CESAR F. QüEB

Hi Roman,

Thank you for all this articles again..

I want a request to you..

Could you share with us the printable document for all related articles about XAF - DC?... Currently does not exist this feature here...

Any way..., this word file (in 2007 format)  has related articles (with comments):

rapidshare.com/.../eXpress_App_Framework_Team_-_DC_technology.docx

TIA

26 September, 2008
CESAR F. QüEB

Hi again,

You can download now the Reusable Domain Models. Interfaces and delegation PDF file (without comments), originally placed at community.devexpress.com/.../382.aspx:

Download the PDF file:

rapidshare.com/.../XAF_-_DC_-_Reusable_Domain_Models._Interfaces_and_delegation.pdf

Regards

27 September, 2008
CESAR F. QüEB

Hi, This PDF file contains all articles related with XAF and DC.  Download it if you want.. for print...

rapidshare.com/.../XAF_-_DC.pdf

Personally, I create this type of document for my archives... sometimes  is better read from a paper that form a PC monitor...

Regards

27 September, 2008
Roman Eremin (DevExpress)

Hello,

Jacha: I'm not ready to discuss how exactly logic override mechanism will work - i don't know it yet :-). We have to find a right balance between flexibility and ease of use and maintainence.

Mohsen: In you scenario you would register IUser as an entity and you'll get what you want.

Alex: Yes, I also not happy about this. That's why we don't like to make promises.

Linton:

Auto generate: I can't agree. I think developer's life is easier when he can control what he is doing.

DC Designer: No promises :-)

FullName and Server mode: Currently it is possible with using PersistentAlias. With DC it will be even easier. I will illustrate this case soon.

drew:

Not sure what do you mean. You'll work with notes like this:

IDeveloper dev = ObjectSpace.FindObject<IDeveloper>(some criteria);

foreach(INote note in dev.Notes) {

  Console.WriteLine(note.Text);

}

Yes, DC approach is more complicated if you write all domain classes by yourself once. But its goal is to provide reusable domain components - meaning you can reuse the component from your other project or (hopefully) from third-party developer.

Also, note that you will write less code.

29 September, 2008
Alex Hoffman

Roman, thanks for the interesting posts!  Really great to see content aimed at software developers, rather than just new or prospective customers.  Can't you convince some of your colleagues to also write technical posts?

My only niggling thought is that perhaps these changes to XAF are the cart pulling the horse.  The future is declarative programming, meaning that rather than have code generate the model, the model should generate the code?

-- Alex Hoffman

expressapp.blogspot.com

29 September, 2008
Roman Eremin (DevExpress)

Hi Alex,

This kind of activity is time consuming and most developers like to write code, not text. But Gary and Oliver could write more in-depth articles, maybe with developer's help. I will talk to them.

Regarding cart and horse - I don't agree. Code is much better than a model. Developers can read the code, there are refactoring tools for code. Code can be compiled and unit tested (as you will see in next posts). Writing interfaces is a declarative programming, but it retains the benefits of being in code.

29 September, 2008
drew..

hey Roman, i think your next post addressed my question..

29 September, 2008
Eric

This framework is interesting, but I'm wondering how is it different from ActiveRecord, NHibernate, etc.

Also, do you have any documentation discussing the pros and cons between this framework and existing ones?

My company has already purchased the DevExperience full package (and are using it with a windows app), so I'm just wondering if we should consider migrating, or is this framework still very much in the experimental phases?

Thanks!

27 October, 2008

Please login or register to post comments.