Constructing an object graph from a flat DTO using visitor pattern - c#

I've written myself a nice simple little domain model, with an object graph that looks like this:
-- Customer
-- Name : Name
-- Account : CustomerAccount
-- HomeAddress : PostalAddress
-- InvoiceAddress : PostalAddress
-- HomePhoneNumber : TelephoneNumber
-- WorkPhoneNumber : TelephoneNumber
-- MobilePhoneNumber : TelephoneNumber
-- EmailAddress : EmailAddress
This structure is completely at odds with the legacy database I'm having to work with, so I've defined a flat DTO which contains the data for each element in the customer graph - I have views and stored procedures in the database which allow me to interact with the data using this flat structure in both directions, this all works fine & dandy :)
Flattening the domain model into a DTO for insert/update is straightfoward, but what I'm having trouble with is taking a DTO and creating the domain model from it... my first thought was to implement a visitor which would visit each element in the customer graph, and inject values from the DTO as necessary, something a bit like this:
class CustomerVisitor
{
public CustomerVisitor(CustomerDTO data) {...}
private CustomerDTO Data;
public void VisitCustomer(Customer customer)
{
customer.SomeValue = this.Data.SomeValue;
}
public void VisitName(Name name)
{
name.Title = this.Data.NameTitle;
name.FirstName = this.Data.NameFirstName;
name.LastName = this.Data.NameLastName;
}
// ... and so on for HomeAddress, EmailAddress etc...
}
That's the theory and it seems like a sound idea when it's laid out simply like that :)
But for this to work the entire object graph would need to be constructed before the visitor erm, visited, otherwise I'd get NRE's left right and centre.
What I want to be able to do is let the visitor assign objects to the graph as it visits each element, with the goal being to utilize the Special Case pattern for objects where data is missing in the DTO, eg.
public void VisitMobilePhoneNumber(out TelephoneNumber mobileNumber)
{
if (this.Data.MobileNumberValue != null)
{
mobileNumber = new TelephoneNumber
{
Value = this.Data.MobileNumberValue,
// ...
};
}
else
{
// Assign the missing number special case...
mobileNumber = SpecialCases.MissingTelephoneNumber.Instance;
}
}
Which I honestly thought would work, but the C# throws me an error on:
myVisitor.VisitHomePhone(out customer.HomePhoneNumber);
Since you can't pass ref/out parameters in this way :(
So I'm left with visiting independent elements and reconstructing the graph when its done:
Customer customer;
TelephoneNumber homePhone;
EmailAddress email;
// ...
myVisitor.VisitCustomer(out customer);
myVisitor.VisitHomePhone(out homePhone);
myVisitor.VisitEmail(out email);
// ...
customer.HomePhoneNumber = homePhone;
customer.EmailAddress = email;
// ...
At this point I'm aware that I'm quite far away from the Visitor Pattern and am much closer to a Factory, and I'm starting to wonder whether I approached this thing wrong from the start..
Has anyone else run into a problem like this? How did you overcome it? Are there any design patterns which are well suited to this scenario?
Sorry for posting such a looong question, and well done for reading this far :)
EDIT In response to the helpful answers from Florian Greinacher and gjvdkamp, I settled on a relatively simple factory implementation that looks like this:
class CustomerFactory
{
private CustomerDTO Data { get; set; }
public CustomerFactory(CustomerDTO data) { ... }
public Customer CreateCustomer()
{
var customer = new Customer();
customer.BeginInit();
customer.SomeFoo = this.Data.SomeFoo;
customer.SomeBar = this.Data.SomeBar
// other properties...
customer.Name = this.CreateName();
customer.Account = this.CreateAccount();
// other components...
customer.EndInit();
return customer;
}
private Name CreateName()
{
var name = new Name();
name.BeginInit();
name.FirstName = this.Data.NameFirstName;
name.LastName = this.Data.NameLastName;
// ...
name.EndInit();
return name;
}
// Methods for all other components...
}
I then wrote a ModelMediator class to handle interaction between the data layer and the domain model...
class ModelMediator
{
public Customer SelectCustomer(Int32 key)
{
// Use a table gateway to get a customer DTO..
// Use the CustomerFactory to construct the domain model...
}
public void SaveCustomer(Customer c)
{
// Use a customer visitor to scan for changes in the domain model...
// Use a table gateway to persist the data...
}
}

I think you are really over-complicating things here. Just use a factory method and let your domain objects clearly state on which other domain objects they depend.
class Customer
{
private readonly Name name;
private readonly PostalAddress homeAddress;
public Customer(Name name, PostalAddress homeAddress, ...)
{
this.name = name;
this.homeAddress = homeAddress;
...
}
}
class CustomerFactory
{
Customer Create(CustomerDTO customerDTO)
{
return new Customer(new Name(...), new PostalAdress(...));
}
}
If you need to take a dependency from Customer to CustomerDTO pass the DTO as additional argument to the constructor, probably wrapped in an additional abstraction.
This way things will keep clean, testable and easy to understand.

I don't think i would go with a visitor. That would be appropriate if you don't know at design time, what operations you need to perform on it later, so you open up the class to allow for others to write visitors that implement that logic. Or there are so many things that you need to do on it that you don't want to clutter your class with this.
What you want to do here is create an instance of a class from a DTO. Since the structure of the class and the DTO are closely linked (you do your mapping in the DB, I assume you handle all mapping issues on that side and have a DTO format that maps directly to the structure of your customer), you know at design time what you need to. There's no need for much flexibility. (You want to be robust though, that the code can handle changes to the DTO, like new fields, without throwing exceptions)
Basically you want to construct a Customer from a snippet of a DTO. What format do you have, just XML or something else?
I think I would just go for a constructor that accepts the DTO and returns a Customer (example for XML:)
class Customer {
public Customer(XmlNode sourceNode) {
// logic goes here
}
}
The Customer class can 'wrap around' an instance of the DTO and 'become one'. This allows you to very naturally project an instance of your DTO into a customer instance:
var c = new Customer(xCustomerNode)
This handles the high level pattern choice. Do you agree so far?
Here's a stab at the specific issue you mention with trying to pass properties 'by ref'.I do see how DRY and KISS can be at odds there, but I would try not to overthink it. A pretty straight forward solution could fix that.
So for the PostalAddress, it would have it's own constructor too, just like the Customer itself:
public PostalAddress(XmlNode sourceNode){
// here it reads the content into a PostalAddress
}
on the customer:
var adr = new PostalAddress(xAddressNode);
The problem I see here is, where do you put the code that figures out if this if the InvoiceAddress or the HomeAddress? This does not belong in the constructor of the PostalAddress, because there could be other uses for the PostalAddress later, you don't want to hardcode it in the PostalAddress class.
So that task should be handled in the Customer class. This is where he usage of the PostalAddress is determined. It needs to be able to tell from the returned Address what type of address it is. I guess the simplest approach would be to just add a property on PostalAddress that tells us:
public class PostalAddress{
public string AdressUsage{get;set;} // this gets set in the constructor
}
and in the DTO just specify it:
<PostalAddress usage="HomeAddress" city="Amsterdam" street="Dam"/>
Then you can look at it in the Customer class and 'stick it' in the right property:
var adr = new PostalAddress(xAddressNode);
switch(adr.AddressUsage){
case "HomeAddress": this.HomeAddress = adr; break;
case "PostalAddress": this.PostalAddress = adr; break;
default: throw new Exception("Unknown address usage");
}
A simple attribute that tells the Customer what type of address it is would be enough I guess.
How does it sound so far? Code below puts it all together.
class Customer {
public Customer(XmlNode sourceNode) {
// loop over attributes to get the simple stuff out
foreach (XmlAttribute att in sourceNode.Attributes) {
// assign simpel stuff
}
// loop over child nodes and extract info
foreach (XmlNode childNode in sourceNode.ChildNodes) {
switch (childNode.Name) {
case "PostalAddress": // here we find an address, so handle that
var adr = new PostalAddress(childNode);
switch (adr.AddressUsage) { // now find out what address we just got and assign appropriately
case "HomeAddress": this.HomeAddress = adr; break;
case "InvoiceAddress": this.InvoiceAddress = adr; break;
default: throw new Exception("Unknown address usage");
}
break;
// other stuff like phone numbers can be handeled the same way
default: break;
}
}
}
PostalAddress HomeAddress { get; private set; }
PostalAddress InvoiceAddress { get; private set; }
Name Name { get; private set; }
}
class PostalAddress {
public PostalAddress(XmlNode sourceNode) {
foreach (XmlAttribute att in sourceNode.Attributes) {
switch (att.Name) {
case "AddressUsage": this.AddressUsage = att.Value; break;
// other properties go here...
}
}
}
public string AddressUsage { get; set; }
}
class Name {
public string First { get; set; }
public string Middle { get; set; }
public string Last { get; set; }
}
and a snippet of XML. You haven't said anything about your DTO format, would work for other formats too.
<Customer>
<PostalAddress addressUsage="HomeAddress" city="Heresville" street="Janestreet" number="5"/>
<PostalAddress addressUsage="InvoiceAddress" city="Theresville" street="Hankstreet" number="10"/>
</Customer>
Regards,
Gert-Jan

For doing conversions between a model class and a DTO, my preference is to do one of four things:
a. use an implicit conversion operator (especially when dealing json-to-dotnet transitions).
public class Car
{
public Color Color {get; set;}
public int NumberOfDoors {get; set;}
}
public class CarJson
{
public string color {get; set;}
public string numberOfDoors { get; set; }
public static implicit operator Car(CarJson json)
{
return new Car
{
Color = (Color) Enum.Parse(typeof(Color), json.color),
NumberOfDoors = Convert.ToInt32(json.numberOfDoors)
};
}
}
and then usage is
Car car = Json.Decode<CarJson>(inputString)
or more simply
var carJson = new CarJson {color = "red", numberOfDoors = "2"};
Car car = carJson;
voila, instant conversion :)
http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx
b. Use linq projection to change the shape of the data
IQueryable<Car> cars = CarRepository.GetCars();
cars.Select( car =>
new
{
numberOfDoors = car.NumberOfDoors.ToString(),
color = car.Color.ToString()
} );
c. Use some combination of the two
d. Define an extension method (that could also be used in the linq projection)
public static class ConversionExtensions
{
public static CarJson ToCarJson(this Car car)
{
return new CarJson {...};
}
}
CarRepository.GetCars().Select(car => car.ToCarJson());

You could take the approch I described here: convert a flat database resultset into hierarchical object collection in C#
The idea behind is to read an object, like Customer and put it into a Dictionary. When reading the data for e.g. CustomerAccount, you can now take the Customer from the Dictionary and add the Customer Account to the customer.
You'll have only one iteration over all data to build your object graph.

Related

Modelling contact details for a person / customer

I was wondering if there was a more elegant way in managing contact details for an individual. Forget the SQL side of things for a moment, I am intrigued in how one would perhaps attempt to drive this via a DDD approach.
I was fooling around with some code in an effort to get comfortable with DDD as a whole and came up with the following which seems awful.
Firstly, I have an object called Person (simplified for the purpose of this post) where I envision methods to add and essentially manage different methods of communicating an individual.
public class Person
{
public Person()
{
this.ContactDetails = new List<ContactDetails>();
}
public void AssociateContactDetails(ContactDetails contactDetails)
{
var existingContactDetails = this.ContactDetails.FirstOrDefault(x => x.ContactType == contactDetails.ContactType);
if (existingContactDetails != null)
{
this.ContactDetails.Remove(existingContactDetails);
}
this.ContactDetails.Add(contactDetails);
}
public IList<ContactDetails> ContactDetails { get; private set; }
}
Two approaches spring to mind. One where I have a fairly simple object like the one below which is quite generic (using the term loosely).
public enum ContactType
{
Email, Telephone, Mobile, Post
}
public class ContactDetails
{
private readonly ContactType contactType;
private readonly string value;
public ContactDetails(ContactType contactType, string value)
{
this.contactType = contactType;
this.value = value;
}
public ContactType ContactType
{
get { return this.contactType; }
}
public string Value
{
get { return this.value; }
}
}
But then I put myself into a corner with this approach as although it works well for trivial items such as email and telephone, when it comes to something like postal a string doesn't quite cut it. Therefore, after this I am heading towards the approach of having each mechanism of communication to represented by its own type, i.e.:
public class Post
{
public Address PostalAddress { get; set; }
}
public class Mobile
{
public string MobileNo { get; set; }
}
public class Telephone
{
public string AreaCode { get; set; }
public string TelephoneNo { get; set; }
}
public class Email
{
public string EmailAddress { get; set; }
}
Each type can then represented as a collection or single instance in the Person class? Seems long winded however is perhaps more readable and maintainable.
The question I guess is if there is a more elegant way in implementing such a feature and whether someone can point me in the direction of a good example similar to this. I imagine this is a common thing / problem to overcome.
Cheers, DS.
We know for sure what are the contact methods "email, "phone" and "address", so having identified those what we have to do first is to model those concepts taking into account what they really are. Let's take "email" as example and see what it really is in order to model it properly. It is a value object (an immutable object) that once created it will never change just as an integer number is an immutable object as well. The difference is that for modelling an integer number we can use the int type provided by any programming language, but the question is what class do we use for modelling en Email? Most of people would use a String instance to model an Email, but is this OK? In order to answer it let's see what is the protocol (the set of messages) a String object knows to response: "charAt(anIndex), replace(aString, anotherString), etc... ". Imagine that if we model an email by using a String class we could ask the email "replace(aString, anotherString)". That sounds weird, that message should not be part of the behavior an email should expose to other objects. Also so so important we said an email is immutable to it cannot expose behavior that at the end change it state. So it makes visible that we need to create a whole new abstraction to model an email and what is it? The Email class finally comes in!!! I know you suggested it but I just wanted to let you see why we need an Email class created.
First of all this is DDD (object oriented) so FORGET avoid setters and getters. In the email class you created you expose a setter method meaning that you can change the email and it contradicts with the nature of what an email is (immutable). An email is immutable from the momento it is created:
Email.fromString("monicalewinsky#gmail.com");
that is the same as doing
new Email("monicalewinsky#gmail.com");
The fromString method is a factory method that adds semantic to our domain model. This is very common in smalltalk instead of calling the constructor directly. Are we done??? Not at all. An email instance should be created as long as it is valid so the email class should assert the string from which is created is valid:
Email(String anEmailStringRepresentation) {
assertIsValid(anEmailStringRepresentation);
}
assert is valid should verify it is actually an email string representation. This is that is has only one # character, its local part is valid and then its domain part is valid. You can check the wikipedia for email address to understand better how it is composed.
Remember always that programming is a learning process, as long as we understand a domain better and better we reflect that domain in the code and it always must be consistent with the real world! Our Email class should look like more or less like:
class Email {
String value;
Email(aString) {
value = aString;
}
public String getLocalPart()
public String getDomainPart()
public String asString()
public boolean equals(anObject)
public static Email fromString(aString)
}
That's it. It happens the same with PhoneNumber. It is also an inmmutable object and you should create a class with its own protocol. Remember never use set/get as you showed up if we are doing DDD. I don't think you need two value objects Telephone and Mobile since those are polymorphic objects and you could model a mobile phone number or a home phone number with the TelephoneNumber abstraction. It's like modelling a credit card. At the end you will end up and understand that the class CreditCard is enough and a better design than having several class such as Visa, MasterCard, and so on.
Let's skip the Address class and let's go back to your problem now.
So far we have identified and created properly all the value objects we need. Now we need to create an abstraction for representing an email, phonenumber, address as contact methods and if we keep loyal to the domain language we could say:
ContactMethod.for(Email.fromString("monica#gmail.com"));
or
ContactMethod.for(PhoneNumber("34234234234"));
etc
so our ContactMethod would look like:
class ContactMethod {
static EMAIL = 1;
static PHONE_TYPE = 2;
static ADDRESS_TYPE = 3;
String type;
String value;
ContactMethod(int aType, String aValue) {
type = aType;
value = aValue;
}
String getType()
String getValue()
public static ContactMethod at(Email anEmail) {
return new ContactMethod(EMAIL, anEmail.asString());
}
public static ContactMethod at(PhoneNumber aPhoneNumber) {
return new ContactMethod(PHONE_TYPE, aPhoneNumber.asString());
}
public static ContactMethod at(Address anAddress) {
return new ContactMethod(ADDRESS_TYPE, anAddress.asString());
}
}
See that ContactMethod is also an immutable class, actually a rule of thumb is that an Aggregate root should have ideally only an aggregation of value objects.
This is finally how your Person class would look like:
class Person {
List<ContactMethod> contactMethods;
contactedAt(Email anEmail) {
contactMethods.add(ContactMethod.at(anEmail));
}
contactedAt(PhoneNumber aPhoneNumber) {
contactMethods.add(ContactMethod.at(aPhoneNumber));
}
contactedAt(Address anAddress) {
contactMethods.add(ContactMethod.at(anAddress));
}
}
On my journey of learning DDD sometimes I see patterns instead of problems... an interesting example Everything seems to be an Aggregate Root is another answer I had provided regarding a menu, which had different categories such as starter, main, desert etc.
I had modeled this implicitly as a category string. After i posted there was a second answer where someone suggested modeling these as explicit lists of:
Menu {
List<Food> starters;
List<Food> entrees;
List<Food> desserts;
List<Food> drinks;
}
In this way, the entire concept of the category for a food was removed, this was enlightening for me and saw a different way of modeling and in this case reducing complexity.
My view is to try and model the code so that if I sat down with the business expert (who is not a developer) and showed them the use case code from a high level person.SetMobileNumber("078321411", Countries.UK) they would be able to understand it:
public void HandleUpdateMobileCommand(UpdateMobileNumber command)
{
// repositories, services etc are provided in this handler class constructor
var user = this.UserRepository.GetById(command.UserId);
user.SetMobile(command.number, command.country);
this.UserRepository.Save(user);
// send an SMS, this would get the number from user.Mobile
this.SmsService.SendThankYouMessage(user);
}
Or even better, you could have a MobileUpdated event get fired when you update the user mobile, to which some code somewhere else (which is an expert on sending SMS messages, and nothing else) is listening to these events - for me this is the real power of DDD of breaking down code in to expert systems.
So in summary, I think your second suggestion of explicitly modeling with Post, Mobile, Landline and Email makes most sense.
I wouldn't say this a DDD domain or not as there isn't enough information on any complex logic (or multi-user race conditions) that you require, just to mention don't forget that you may be better writing a CRUD app if that makes more sense in this situation.
There's this central idea in DDD that domain modelling must take shape through discussion with domain experts. If you're making up these class names out of thin air, chances are they won't exactly match your real domain. Trivial ones such as Email or Telephone should be correct, but maybe for others you want feedback from an expert first.
Generally speaking, it's a good idea indeed to favor semantically rich modelling with dedicated value objects over primitive types. In C# it comes at a cost though since the amount of boilerplate code needed is huge (unlike F# for instance). This is why I usually prefer to do it only when the type has more than a single property or when there are specific construction rules or invariants to it.
One good thing you can do is model your types as immutable Value Objects. So something like:
public class Telephone
{
public string AreaCode { get; set; }
public string TelephoneNo { get; set; }
}
Might become:
public class TelephoneNumber
{
private string areaCode;
private string subscriberNumber;
private TelephoneNumber()
{
}
public TelephoneNumber(string areaCode, string subscriberNumber)
{
this.AreaCode = areaCode;
this.SubscriberNumber = subscriberNumber;
}
public string AreaCode
{
get
{
return this.areaCode;
}
private set
{
if (value == null)
{
throw new ArgumentNullException("AreaCode");
}
if ((value.Length <= 0) || (value.Length > 5))
{
throw new ArgumentOutOfRangeException("AreaCode");
}
this.areaCode = value;
}
}
// Etc.
}

Neo4jClient does not add properties to a relationship

We have been trying to write a C# client that seeds a Neo4j instance with some nodes and relationships. We are facing probelms when trying to create relationship properties.
Here is the code to create the relatioship with the flag property:
var s = clientConnection.CreateRelationship(root, new RelationshipPrincipleToContent("SECURITY", rootFolder) { flags = "+W" });
Here is the relationship class:
public class RelationshipPrincipleToContent : Relationship, IRelationshipAllowingSourceNode<Principles>, IRelationshipAllowingTargetNode<Content>{
public string flags { get; set; }
string RelationshipName;
public RelationshipPrincipleToContent(NodeReference targetNode) : base(targetNode){}
public RelationshipPrincipleToContent(string RelationshipName, NodeReference targetNode): base(targetNode){
this.RelationshipName = RelationshipName;
}
public override string RelationshipTypeKey{
get { return RelationshipName; }
}
}
When we look at the data in the data browser tab there are no properties on the relationships. We have also created a relationship index?
What are we missing/ doing wrong?
Firstly add a class (PayLoad.cs in this instance) that holds a set for a public string.
public class PayLoad
{
public string Comment { get; set; }
}
Update your relationship class to use this PayLoad class:
public class RelationshipPrincipleToContent : Relationship<PayLoad>, IRelationshipAllowingSourceNode<Principles>, IRelationshipAllowingTargetNode<Content>
{
string RelationshipName;
public RelationshipPrincipleToContent(string RelationshipName, NodeReference targetNode, PayLoad pl)
: base(targetNode, pl)
{
this.RelationshipName = RelationshipName;
}
public override string RelationshipTypeKey
{
get { return RelationshipName; }
}
}
}
Now just update your method call on the relationship class:
clientConnection.CreateRelationship(AllPrincipals, new RelationshipPrincipleToContent("SECURITY", rootFolder, new PayLoad() { Comment = "+R" }));
(Context: I lead the Neo4jClient project.)
Shaun's answer is correct, however dated.
The direction of both Neo4j and Neo4jClient is towards Cypher as a unified approach to everything you need to do.
This Cypher query:
START root=node(0), rootFolder=node(123)
CREATE root-[:SECURITY { flags: 'W+' }]->rootFolder
Is this in C#:
client.Cypher
.Start(new { root = client.RootNode, rootFolder })
.Create("root-[:SECURITY {security}]->rootFolder")
.WithParam("security", new { flags = "+W" })
.ExecuteWithoutResults();
Some notes:
Using Cypher for this type of stuff might look a bit more complex to start with, but it will grow better for you. For example, a simple switch from Create to CreateUnique will ensure you don't create the same relationship twice; that would be much harder with the procedural approach.
Non-Cypher wrappers in Neo4jClient are a bit old and clunky, and will not see any significant investment moving forward
The C# approach uses WithParam to ensure that everything gets encoded properly, and you can still pass in nice objects
The C# approach uses WithParam to allow query plan caching

Accessing custom objects in DomainService from client

I am using Domain Service to fetch data from database from Silverlight Client.
In DomainService1.cs, I have added the following:
[EnableClientAccess()]
public class Product
{
public int productID;
public string productName;
public List<Part> Parts = new List<Part>(); //Part is already present in Model designer
}
In DomainService1 class I added a new method to retrive a collection of the custom class object:
[EnableClientAccess()]
public class DomainService1 : LinqToEntitiesDomainService<HELPERDBNEWEntities1>
{
...
public List<Product> GetProductsList(...)
{
List<Product> resultProducts = new List<Product>();
...
return resultProducts;
}
}
From the silverlight client I am trying to access that method:
DomainService1 ds1 = new DomainService1();
var allproductList = ds1.GetProductsList(...);
ds1.Load<SLProduct>(allproductList).Completed += new EventHandler(Load_Completed); //Not correct usage
However it is not the correct way to call the new method. The reason I added a new class Product in DomainServices.cs is to have an efficient grouping. I cannot achieve the same using the model classes auto-generated by the entity framework.
How call I call the new method from the client?
I believe there is a similar question with an answer here:
Can a DomainService return a single custom type?
Also, here is some discussion about the overall problem of adding custom methods in a Domain Service:
http://forums.silverlight.net/t/159292.aspx/1
While I don't know what you mean by "it is not the correct way to call the new method", or if you're getting any errors, I thought maybe posting some working code might help.
My POCO
public class GraphPointWithMeta
{
[Key]
public Guid PK { get; set; }
public string SeriesName { get; set; }
public string EntityName { get; set; }
public double Amount { get; set; }
public GraphPointWithMeta(string seriesName, string entityName, double amount)
{
PK = Guid.NewGuid();
SeriesName = seriesName;
EntityName = entityName;
Amount = amount;
}
// Default ctor required.
public GraphPointWithMeta()
{
PK = Guid.NewGuid();
}
}
A method in the domain service (EnableClientAccess decorates the class)
public IEnumerable<GraphPointWithMeta> CallingActivityByCommercial()
{
List<GraphPointWithMeta> gps = new List<GraphPointWithMeta>();
// ...
return gps;
}
Called from the Silverlight client like
ctx1.Load(ctx1.CallingActivityByCommercialQuery(), CallingActivityCompleted, null);
client call back method
private void CallingActivityCompleted(LoadOperation<GraphPointWithMeta> lo)
{
// lo.Entities is an IEnumerable<GraphPointWithMeta>
}
I am not sure if your Product class is an actual entity or not. From the way it is defined, it does not appear to be an entity. My answer is assuming it is not an entity. You will need to apply the DataMemberAttribute for your Product properties, and you wouldn't load the product list - load is for Entity Queries (IQueryable on the service side). You would just invoke it like this (client side):
void GetProductList( Action<InvokeOperation<List<Product>>> callback)
{
DomainService ds1 = new DomainService();
ds1.GetProductsList(callback, null);//invoke operation call
}
And the domain service's (server side) method needs the InvokeAttribute and would look like this:
[EnableClientAccess]
public class MyDomainService
{
[Invoke]
public List<Product> GetProductList()
{
var list = new List<Product>();
...
return list;
}
}
And here is how your Product class might be defined (if it is not an entity):
public class Product
{
[DataMember]
public int productID;
[DataMember]
public string productName;
[DataMember]
public List<Part> Parts = new List<Part>(); // you might have some trouble here.
//not sure if any other attributes are needed for Parts,
//since you said this is an entity; also not sure if you
//can even have a list of entities or it needs to be an
//entity collection or what it needs to be. You might
//have to make two separate calls - one to get the products
//and then one to get the parts.
}
Like I said, i am not sure what Product inherits from... Hope this helps.

C#, problem mixing Xml Serialization with Nhibernate

I am working on a program that uses Nhibernate to persist objects, and Xml Serialization to import and export data. I can't use the same properties for collections as, for example, Nhibernate needs them to be Ilists, because it has it's own implementation of that interface, and I can't Serialize interfaces. But as I need both properties to be synchronized, I thought I could use two different properties for the same Field. The properties will be according to what I need for each framework, and they will update the Field accrodingly.
So, I have the following field:
private IList<Modulo> modulos;
And the following properties:
[XmlIgnore]
public virtual IList<Modulo> Modulos
{
get { return modulos; }
set { modulos = value; }
}
[XmlArray]
[XmlArrayItem(typeof(Modulo))]
public virtual ArrayList XmlModulos
{
get
{
if (modulos == null) return new ArrayList();
var aux = new ArrayList();
foreach (Modulo m in modulos)
aux.Add(m);
return aux;
}
set
{
modulos = new List<Modulo>();
foreach (object o in value)
modulos.Add((Modulo)o);
}
}
The first one is working perfectly, being quite standard, but I have some problems with the second one. The get is working great as I am having no problems Serializing objects (meaning it correctly takes the info from the field). But when I need to Deserialize, it is not getting all the info. The debugger says that after the Deserialization, the field is not updated (null) and the Property is empty (Count = 0).
The obvious solution would be using two unrelated properties, one for each framework, and passing the information manually when needed. But the class structure is quite complicated and I think there should be a more simple way to do this.
Any Idea how I can modify my property for it to do what I want? Any help will be appreciated.
The short answer is that you cant.
Typically you would create a DTO ( Data transfer object ) separate from your NHibernate objects. For example:
public class PersonDto
{
[XmlAttribute(AttributeName = "person-id")]
public int Id { get; set; }
[XmlAttribute(AttributeName = "person-name")]
public string Name{ get; set; }
}
On your DTO object you only put the properties that you intend to serialize. You than create a DTO from your domain model when you need to serialize one.
There is a great little library called automapper that makes mapping from your domain objects to your dto's pretty straight forward. See: http://automapper.codeplex.com/
Here is an example of a person class that supports mapping to the above DTO.
public class Person
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
static Person()
{
Mapper.CreateMap<PersonDto, Person>();
Mapper.CreateMap<Person, PersonDto>();
}
public Person(PersonDto dto)
{
Mapper.Map<PersonDto, Person>(dto, this);
}
public PersonDto ToPersonDto()
{
var dto = new PersonDto();
Mapper.Map<Person, PersonDto>(this, dto);
return dto;
}
}

C# class organization and lists

I am working on a C# application which consists of objects Department, Course, and Section. Each Department has many Courses, and each Course has many Sections. Currently I have three classes: Department, Course, and Section. Department contains some properties and then a List Courses, which contains the courses the department offers. Course contains some properties and then a List Sections, which contains the sections of the course. Is this a good way to have the code structured or should I be doing it a different way?
Secondly, when I instantiate a department in my application, I set some properties and then would like to begin adding courses to the List Courses defined in the Department class. However, I seem to be unable to simply do Department.Courses.Add(Course) from the application. What must I do within the Department class so that I may add objects to that list without breaking the principle of encapsulation?
An example of what I have with the list right now is:
class Department
{
// ......
List<Course> Courses = new List<Course>;
}
however Department.Courses is not available in the program code after the class has been instantiated (all other properties of the class are available).
Instantiate the internal Courses list inside the parameterless constructor of your class.
private List<Course> _coursesList;
public Department()
{
_coursesList = new List<Course>();
}
Also, another way to ensure the encapsulation is to provide a method on your Department class to add the courses to it instead of directly exposing the courses list. Something like
public void AddCourse(Course c) { ... }
// or (adding the feature of doing the method calls in a composable way)
public Course AddCourse(Course c) { ... }
// or
public void AddCource(String name, etc) { ... }
I think in your case it is not a good idea do directly exposes the List because the class List, may provide methods like, Add and Remove which could potentially creates an invalid state on your parent class. So if you choose to expose methods to manipulate the internal collections like I suggested, you could expose an array of Courses to your API clients (remember the arrays are read-only) so your API consumers won't be able to the create side effects on your department class.
public Course[] Courses {
get { return _coursesList.ToArray(); }
}
In addition, you could also implement the IEnumerable interface on your Department class. It would enable you to take advantage of the all LINQ extension methods available in C# 3.0.
I hope it helps,
Carlos.
Probably something Similar. There are several ways of soing this. depends upon what your requirements are.
public class Department
{
// Initialize the list inside Default Constructor
public Department()
{ courses = new List<Course>(); }
// Initialize List By Declaring outside and Passing with Dpartment Initilization
public Department(List<Course> _courses)
{ courses = _courses; }
List<Course> courses;
public List<Course> Courses
{
get
{
if (courses == null)
return new List<Course>();
else return courses;
}
set { courses = value; }
}
internal bool AddCourseToCourses(Course _course)
{
bool isAdded = false;
// DoSomeChecks here like
if (!courses.Contains(_course))
{
courses.Add(_course);
isAdded = true;
}
return isAdded;
}
}
public class Course
{
public Course(List<Subject> _subject)
{ subjects = _subject; }
List<Subject> subjects;
public List<Subject> Subjects
{
get { return subjects; }
set { subjects = value; }
}
}
// I do not get what do you mean by course "section", very general.
// used Subject instead, Change as you want just to give an idea
public class Subject
{
string name;
public string Name
{
get { return name; }
set { name = value; }
}
int creditHours;
public int CreditHours
{
get { return creditHours; }
set { creditHours = value; }
}
public Subject(string _name, int _creditHours)
{
name = _name;
creditHours = _creditHours;
}
}
public class TestClass
{
public void DoSomething()
{
// Subjects
Subject subj1 = new Subject("C#", 10);
Subject subj2 = new Subject(".Net", 10);
// List of Subjects
List<Subject> advancedPrSubjects = new List<Subject>();
advancedPrSubjects.Add(subj1);
advancedPrSubjects.Add(subj2);
// Course
Course advancedProgramming = new Course(advancedPrSubjects);
// Deliver authoroty to add Course to Department Class itself
Department dept = new Department();
dept.AddCourseToCourses(advancedProgramming);
}
}
There are better ways of doing this. have a look at these tutorials for better insight
http://www.csharp-station.com/Tutorials/Lesson07.aspx
http://www.functionx.com/csharp/index.htm
Hope it helps
As to your second question - without some code or more details its a bit hard - but i'll take a guess.
You're probably not actually creating the list, just declaring it
List<xxxx> _variable;
vs
List<xxxx> _variable = new List<xxxxx>();
You must create a list to be able to add to it (new List());
You sound as if you're on the right track.
Your second problem could be down to many things.
It could be as Ruddy says and that you're not creating the list.
It could also be that your Courses List is not public or that you haven't instanciated a new Course object to add.

Categories

Resources