I am trying to work out the best way to design a class that has its properties persisted in a database. Let's take a basic example of a Person. To create a new person and place it in the database, I want the DateOfBirth property to be optional (i.e. NULLable in the DB).
Here's my sample code:
namespace BusinessLayer
{
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
}
I'm unsure as to whether the fields should be public or not. Should I do it like this:
class Program
{
static void Main(string[] args)
{
Person person1 = new Person("Kate","Middleton",null);
}
}
or like this:
class Program
{
static void Main(string[] args)
{
Person person1 = new Person();
person1.FirstName = "Kate";
person1.LastName = "Middleton";
}
}
I'm also wondering how I should be dealing with the optional properties of the class. Once the fields have been populated how do I then save them to the DB? I have a DatabaseComponenet class to save the information. How do I deal with the optional when saving to the database?
So, would I do something like this:
public int Save()
{
int personId;
personId = DatabaseComponent.InsertPerson(FirstName, LastName, DateOfBirth);
return personId;
}
Thanks for any help! Some useful URLs on good class design would also be appreciated.
First, I'd put two distinct public constructor to Person:
namespace BusinessLayer
{
class Person
{
public Person(string firstName, string lastName): this(firstName, lastName, DateTime.Now)
{}
public Person(string firstName, string lastName, DateTime birthDate)
{
FirstName = firstName;
LastName = lastName;
DateOfBirth = birthDate;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
}
this allows you to write both
var p = new Person("Marilyin", "Manson");
var p2 = new Person("Alice", "Cooper", new DateTime(...));
and
var p = new Person { FirstName="Marilyn", LastName="Manson" };
I can't see why you should limit to only one form.
As for the DatabaseComponent I'd strongly suggest to write a method that allows you to save a Person instead of the signature you are implicitly declaring.
That's because, should one day change the way a Person is defined, you'd probably have to change the code in each point you invoke Save() method. By saving just a Person, you only have to change the Save() implementation.
Don't you plan to use an ORM by the way?
With C# 3.0 class initializers I no longer bother of providing a constructor that allows me to initialize all properties:
var person1 = new Person
{
FirstName = "Kate";
LastName = "Middleton";
};
As far as the Save method is concerned I usually put them in a separate repository class:
public int Save(Person person)
{
...
}
and then when I need to save a person I do:
var person1 = new Person
{
FirstName = "Kate";
LastName = "Middleton";
};
var id = new PersonsRepository().Save(person1);
Only use constructors if some fields are mandatory since it's an effective way to make sure that those fields are specified.
I'm unsure as to whether the fields should be public or not
Fields usually means member variables and those should always be private. As for properties I would stick with get/set for database objects.
I'm also wondering how I should be dealing with the optional properties of the class. Once the fields have been populated how do I then save them to the DB?
Saving things to the database is a whole different story. I would not try to invent my own layer but to use an existing one. There are a whole set of different ORM:s out there from very simple to very feature complete.
Take a look at PetaPoco for a lightweight alternative or nHibernate for a more feature complete alternative.
Validation
One common way to make sure that mandatory fields are correctly specified and got valid values are to use a validation framework. There is one built into .net called DataAnnotations. Google it and look at some examples.
This should be checked by using business rules.
I mean if you want a very re-usable business model, business objects should be re-used elsewhere in different areas, and this may mean same class "A" could be fine in state "X" in some business, but in another situation, same class "A", will be fine in state "Y".
There's a good design pattern allowing you to implement business validators called Specification:
http://en.wikipedia.org/wiki/Specification_pattern
This can be implemented in a lot of ways, but one of most compact ones is by building rules with lambda expressions.
For example:
someAInstance => someAInstance.Name != null && someAInstance.Age > 30
Another way is using existing object validation libraries, like NHibernate Validator, which can be used standalone without NHibernate and allows you to put attributes in class' properties like [NotNull], [NotNullNotEmpty], and more complex rules, and you can either use built-in ones or you can build your own ones.
Learn more by reading this article (there you'll find a list of out-of-the-box validation rules):
http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx
Note that one of most important advantages of NH Validator is it can be used in any layer, not only data or business layer, and as you can use it without NHibernate, you've a light-weight, easy-to-use and multi-layered object validator.
Related
I'm writing a wrapper around certain functions of mongodb to enforce certain buisiness policies (such as having a last modified date, a document version &c). These extra fields will not appear in the model and will be irrelevant and transparent to the person implementing against this library. This library will be generic.
Therefore using replaceOne is out of the question.
What I would like is some way of passing all fields in a person passed object to the Update builder - so I can use .Set/.Inc accordingly to add the other fields.
An example to demonstrate what I want is below:
public static async Task UpdatePerson(string name, Person person)
{
var client = new MongoClient("mongodb://localhost:27017");
IMongoDatabase db = client.GetDatabase("test");
IMongoCollection<Person> collection = db.GetCollection<Person>("people");
var query = Builders<Person>.Filter
.Eq("name", name);
var update = Builders<Person>.Update
//Something here - how do I pass my person's properties?
.Set("lastModified", DateTime.Now)
.Inc("version",1);
await collection.UpdateOneAsync(query, update );
}
//--
//In real life this'll work for other types, this is for demonstration only
public class Person
{
public string name {get;set;}
public string surname {get;set;}
}
So how can I go about this, without, for instance, looping through properties using Reflection?
Not sure if you are able to do this but the Mongodb Driver provides something called [BsonExtraElements].
public class Person
{
public string name {get;set;}
public string surname {get;set;}
[BsonExtraElements]
public Dictionary<string,object> AdditionalFields { get; set; }
}
What will happen is that anything that cant be serialized to the model will be filled into that dictionary, no matter the type. You can add to it as well and remove.
This will add no additional overhead to your database, The only downside to this is that querying this dictionary is somewhat not a great experience as you may need to cast specific keys to their relevant expected types.
If this is not viable I suggest the BSON approach recommended by Simon.
I am working with Kinect for Windows version 2 and meet a problem. I try to serialize the Body object and send it through the Internet. However Body object is not sterilisable. Although I can extract some key information from a Body object and create my own object, I may lose some information. My question is how to clone all information from a Body object to my own serializable object?
Thank you.
If cloning is what you're concerned with, use AutoMapper.
First you'll need to install AutoMapper using NuGet...
PM> Install-Package AutoMapper
Then check out this example and adapt it to your own needs...
void Main()
{
AutoMapper.Mapper.CreateMap<User, MyUser>()
.ForMember(myUsers => myUsers.Name, users => users.MapFrom(property => string.Format("{0} {1}",property.FirstName, property.LastName)));
User user = new User
{
FirstName = "James",
LastName = "Doe",
DateOfBirth = DateTime.UtcNow
};
MyUser myUser = AutoMapper.Mapper.Map<MyUser>(user);
}
public class MyUser
{
public string Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class User
{
public User()
{
this.Id = Guid.NewGuid().ToString();
}
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
In the example above, AutoMapper figures out that it can map the Id property of MyUser and User class because they're named identically, however we needed to create a custom map to map User.FirstName and User.LastName to MyUser.Name property.
If the purpose of serialization is to reconstruct it at the other end, the first thing you need to determine whether the constructor and setters exist for you to create an equivalent on the other side. If it is purely for an independent representation that your server side needs to interact with, you have a much simpler task.
My recommendation would be to inspect the body object both via the public interface available through documentation and via reflection in the debugger to determine what data you can and want to extract and build a custom, serializable class based on that hierarchical model.
If all the data you need to extract is publicly accessible, simply writer a builder class that takes the body object as its input and constructs your custom class as the output. If it's not publicly accessible, you may need to use reflection to explore the pieces you need. I would advise the reflection code to be manually built as to avoid cycles in the object graph that may exist in a private class as this.
It's alright. Just do the following logic:
Use reflection to loop through the properties of the object you wanna clone.
You can setup the data with your predefined custom class. (Perhaps you might want to generate the XML schema according to the object's properties and from there you create your own predefined custom class).
Hope this concept helps. If not, let's discuss further.
This question already has answers here:
OO Design - do you use public properties or private fields internally? [duplicate]
(10 answers)
Closed 9 years ago.
class Student
{
private string firstName;
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value; // Possible logical checks may be implemented here in the future
}
}
public Student (firstName)
{
this.firstName = firstName; // Option 1
// Or
FirstName = firstName; // Option 2
}
}
which of the two lines is more standard?
do we use the private or the public members in the constructor?
You could go with option 3
public string FirstName {get; set;}
public Student (firstName)
{
FirstName = firstName;
}
It depends... Often on things not included in your example. For one thing, your entire property can be shortened to an auto-implemented property:
public string FirstName { get; set; }
Which would make the question moot in this case. Beyond that, the question comes down to what sort of logic may exist (now or in the future) in the property and whether or not that logic needs to be invoked by the constructor.
For example, does the property internally check for a required value or perform some other validation? Something like this:
private string firstName;
public string FirstName
{
get { return firstName; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentNullException("FirstName");
firstName = value;
}
}
In a case like this clearly you'd want the constructor to use the property and not the backing field so that the logic is applied when constructing the object.
Conversely, you might have logic that should only be used when accessing the setter but not when constructing the object. Off the top of my head one example might be an object which maintains information about a Location. It might have an Address property and a Coordinates property, and any time one of them changes there is a back-end process to geolocate the new value and update the other. But you might have a constructor which accepts both (perhaps when re-building an existing Location from a database) and it wouldn't make sense to perform the geolocation during construction. In that case you'd set the backing fields and not the properties.
For lack of a compelling reason not to use the properties, I'd generally prefer to use them instead of the backing fields. Simply because logic might be added to those properties later that all accessors should use. I also find it more likely that the properties have a more meaningful name than backing fields (for example, FirstName is more readable/meaningful than _firstName) so the preference would be to keep the rest of the code as readable as possible and to prefer more readable names.
It is a stylistic choice that doesn't really matter. Personally, I use the public property name, because I like to use auto properties, and that is the only option in that case. Using the public property keeps my code consistent.
When I am writing POCOs (Plain Old CLR Objects) where things are trivial, I go with this approach:
public class POCO
{
public POCO()
{
Name = "Moo-Juice";
}
public string Name { get; set; }
}
In non-trivial cases where I actually need the member variable, I prefix it with _ (this helps in intellisense, believe me - and allows you to distinguish between members and locals):
public class NonTrivial
{
private string _name;
public NonTrivial()
{
_name = "Jon Skeet"; // He is non-trivial
}
}
This way I avoid polluting my code with this. everywhere.
It depends:
private string firstName;
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = (value=="mycheck")?"default":value;
}
}
If your property has some validations then you should go for:
public Student (firstName)
{
FirstName = firstName;
}
The most common is to use the property, but it is a matter of choice.
In this case particularly, you should use automatic property:
public string FirstName { get; set; }
And the compiler adds the backing field automatically.
You can also choose to not add the parameter constructor, as since C# 3.5 (IIRC), you can use automatic initializers:
new Studant() { FirstName = "John Doe" }
Which calls the constructor, and sets the property in one line.
Overall, I tend to only request a constructor parameter for things it really depend on (see: dependency injection), and let the not always needed ones optional until they are required, like validating before persisting.
This seems to be very stupid and rudimentary question, but i tried to google it, but couldn't a find a satisfactory answer,
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(){}
public Person(string name, int age)
{
Name = name;
Age = age;
}
//Other properties, methods, events...
}
My question is if i have class like this, what is the best way to create an object?
Person p=new Person("abc",15)
OR
Person p=new Person();
p.Name="abc";
p.Age=15;
What is the difference between these two methods and what is the best way to create objects?
Decide if you need an immutable object or not.
If you put public properties in your class, the state of every instance can be changed at every time in your code. So your class could be like this:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(){}
public Person(string name, int age)
{
Name = name;
Age = age;
}
//Other properties, methods, events...
}
In that case, having a Person(string name, int age) constructor is not so useful.
The second option is to implement an immutable type. For example:
public class Person
{
public string Name { get; private set; }
public int Age { get; private set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
//Other properties, methods, events...
}
Now you have a constructor that sets the state for the instance, once, at creation time. Note that now setters for properties are private, so you can't change the state after your object is instantiated.
A best practice is to define classes as immutable every time if possible. To understand advantages of immutable classes I suggest you read this article.
Really depends on your requirement, although lately I have seen a trend for classes with at least one bare constructor defined.
The upside of posting your parameters in via constructor is that you know those values can be relied on after instantiation. The downside is that you'll need to put more work in with any library that expects to be able to create objects with a bare constructor.
My personal preference is to go with a bare constructor and set any properties as part of the declaration.
Person p=new Person()
{
Name = "Han Solo",
Age = 39
};
This gets around the "class lacks bare constructor" problem, plus reduces maintenance ( I can set more things without changing the constructor ).
There's not really a best way. Both are quite the same, unless you want to do some additional processing using the parameters passed to the constructor during initialization or if you want to ensure a coherent state just after calling the constructor. If it is the case, prefer the first one.
But for readability/maintainability reasons, avoid creating constructors with too many parameters.
In this case, both will do.
In my humble opinion, this is just a matter of deciding if the arguments are optional or not. If an Person object shouldn't (logically) exist without Name and Age, they should be mandatory in the constructor. If they are optional, (i.e. their absence is not a threat to the good functioning of the object), use the setters.
Here's a quote from Symfony's docs on constructor injection:
There are several advantages to using constructor injection:
If the dependency is a requirement and the class cannot work without it then injecting it via the constructor ensures it is present when the class is used as the class cannot be constructed without it.
The constructor is only ever called once when the object is created, so you can be sure that the dependency will not change during the object's lifetime.
These advantages do mean that constructor injection is not suitable for working with optional dependencies. It is also more difficult to use in combination with class hierarchies: if a class uses constructor injection then extending it and overriding the constructor becomes problematic.
(Symfony is one of the most popular and respected php frameworks)
If you think less code means more efficient, so using construct function is better.
You also can use code like:
Person p=new Person(){
Name='abc',
Age=15
}
how about
var obj = new {ID = 1, Price = 2};
Depends on your requirment, but the most effective way to create is:
Product obj = new Product
{
ID = 21,
Price = 200,
Category = "XY",
Name = "SKR",
};
Or you can use a data file to put many person objects in to a list or array. You do need to use the System.IO for this. And you need a data file which contains all the information about the objects.
A method for it would look something like this:
static void ReadFile()
{
using(StreamWriter writer = new StreamWriter(#"Data.csv"))
{
string line = null;
line = reader.ReadLine();
while(null!= (line = reader.ReadLine())
{
string[] values = line.Split(',');
string name = values[0];
int age = int.Parse(values[1]);
}
Person person = new Person(name, age);
}
}
I have the following DB model:
**Person table**
ID | Name | StateId
------------------------------
1 Joe 1
2 Peter 1
3 John 2
**State table**
ID | Desc
------------------------------
1 Working
2 Vacation
and domain model would be (simplified):
public class Person
{
public int Id { get; }
public string Name { get; set; }
public State State { get; set; }
}
public class State
{
private int id;
public string Name { get; set; }
}
The state might be used in the domain logic e.g.:
if(person.State == State.Working)
// some logic
So from my understanding, the State acts like a value object which is used for domain logic checks. But it also needs to be present in the DB model to represent a clean ERM.
So state might be extended to:
public class State
{
private int id;
public string Name { get; set; }
public static State New {get {return new State([hardCodedIdHere?], [hardCodeNameHere?]);}}
}
But using this approach the name of the state would be hardcoded into the domain.
Do you know what I mean? Is there a standard approach for such a thing? From my point of view what I am trying to do is using an object (which is persisted from the ERM design perspective) as a sort of value object within my domain. What do you think?
Question update:
Probably my question wasn't clear enough.
What I need to know is, how I would use an entity (like the State example) that is stored in a database within my domain logic. To avoid things like:
if(person.State.Id == State.Working.Id)
// some logic
or
if(person.State.Id == WORKING_ID)
// some logic
Your proposed structure seems fine. (Terminology digression: since State has an ID, it's not a Value Object, but rather an Entity.)
Enums are a code smell, so don't attempt to go that route. It's much more object-oriented to move the behavior into the State object using the State pattern.
Instead of having to write
if (person.State == State.Working)
// do something...
all over your code, this would allow you to write
person.State.DoSomething();
That's much cleaner, and will allow you to add new States if need be.
A previous question of mine unearthed some useful links that I suspect are pertinent to your question, in particular Jimmy Bogard's discussions of Enumeration Classes.
It's a common practice to include an 'Unknown' element with value 0 in an enum. You can do this and use it for the New state if you really want to.
But what you are describing is business logic... setting a state after creating a new object should then happen in the business logic layer, not inside the class itself.
You want to create a factory method that will instantiate the appropriate state class needed, based on the value stored.
something like
public static State GetStateByID( StateEnum value)
{
if(value.Invalid)
throw new Exception();
switch(value)
case State.Working
return new WorkingState();
case State.somethingelse
return new somethingelseState();
case State.something
return new somethingState();
case State.whatever
return new whateverState();
}
When using enums always try to use 0 as Invalid. Under the hood an enum is a value type, and an unassigned int is always 0.
It is common to use a factory, such as this, in conjunction with the state pattern.
So when you read your stored integer value from the database you can cast the int to the enum and call the factory with it to get the appropriate State object.
I personally think it's a mistake to program against IDs. Instead, I would amend your table to the following:
**State table**
ID | Desc | IsWorking | IsVacation
-----------------------------------------------------------
1 Working True False
2 Vacation False True
I would then use these attributes to make business decisions on such as:
public void MakeDecisionOnState(State state)
{
if (state.IsVacation)
DoSomething();
if (state.IsWorking)
DoSomethingElse();
}
Or by being even more clever, use the factory pattern to create the correct instance based on these attributes:
public abstract class State
{
public Guid Id { get; set; }
public string Description { get; set; }
public abstract void DoSomething();
}
public class WorkingState : State
{
public override void DoSomething()
{
//Do something specific for the working state
}
}
public class VacationState : State
{
public override void DoSomething()
{
//Do something specific for the vacation state
}
}
public class StateFactory
{
public static State CreateState(IDataRecord record)
{
if (record.GetBoolean(2))
return new WorkingState { Id = record.GetGuid(0), Description = record.GetString(1) };
if (record.GetBoolean(3))
return new VacationState { Id = record.GetGuid(0), Description = record.GetString(1) };
throw new Exception("Data is screwed");
}
}
Now you've eliminated the if/switch statement, and your code could simply be:
state.DoSomething();
The reason why I do this is that often these types of entities can be configured by the customer, i.e. they may not want to have some of the states active in the system, or they may wish to term them something else. By programming against the attributes the customer can delete / edit the records as they please and even if that process generates new ID's it doesn't affect the system, they just need to set the attributes.
In my opion the domain layer has to be seperated from the DB model / ERM design. I had trouble understanding your final suggestion for the State class. IMHO this is not a good thing for establishing a common language which is one of the main purposes of DDD.
I would go for a simpler design. The state belongs to the Person class. I would include it in the class.
public class Person
{
public int Id { get; }
public string Name { get; set; }
public PersonState State { get; set; }
}
The state itself seems to have defined values (I assume a person is an employee in your context) which don't change very often. So I would model it as enum and treat it as a data type.
enum Days {Working, Vacation};
This is a simple to understand design in my opinion. The mapping to the ERM design belongs IMHO in the persistence layer. There the enum has to be mapped to the key of the state table. This could be done using an aspect to keep the original domain model clean.