I am trying to synchronise changes to a DataContract between my service and it's consumers. I am having trouble designing a maintainable way of informing of property changes.
For example, I want to keep the below synchronised:
[DataContract]
public class MyObject
{
[DataMember]
public Guid Id { get; private set; } = Guid.NewGuid();
[DataMember]
public int Foo { get; set; }
[DataMember]
public string Bar { get; set; }
}
My original approach was to use an event which took a property name and an object, as such:
public delegate void PropertyChangedEventHandler(Guid id, string propertyName, object value);
The service & consumers could then subscribe to the property changes:
myObject.PropertyChanged += MyObjectPropertyChanged;
// MyObject would raise the property change inside of the property set.
private void MyObjectPropertyChanged(Guid id, string propertyName, object value)
{
// Depending on which end is listening the service can send
// the change to the consumer or vica versa
}
I have encountered an issue using this method as the serializer could not determine how to serialize object.
I now don't know how to handle informing of changes. I can see two approaches but I am hoping for a better solution.
I could inform the consumer/service that a change has been made. It can then request from the service/consumer for the changed MyObject. I see this being a problem if more than one consumer changes the same object at the same time (as the service is concurrency is set to multiple). It could result in one consumer's changes being lost.
The second approach is to create an EventArgs, which mirrors the properties of the MyObject and you access the property based on the property name passed with the EventArgs and synchronise the local copy. This would allow two consumers to change different properties without fear of either being lost. However this feels like a lot of repeated code. A lot of unused data is also passed around as MyObject grows. Admitidly there is room for reflection in regards to reading and setting the appropriate property.
For example:
public class MyObjectPropertyChangedEventArgs : EventArgs
{
public Guid Id { get; set; }
public string PropertyName { get; set; }
// Then one of the relative property below would be set to the new value
public int Foo { get; set; }
public string Bar { get; set; }
}
I don't see this being an uncommon use case and was hoping for some insight into how this is usually done?
As far as service is concerned, why do not you leverage of CallbackContract in order to notify client that some changes occured?
On client side in turn DataContract can implement INotifyPropertyChanged interface and whenever change to any property takes place then you call service.
Related
i know the model should not have any logic , but i don't know where is the good place to put the checking or the update function for a particular model
ex.
public class GuestBook
{
public int money { get; set; }
[Required]
public string name { get; set; }
[Required]
public string email { get; set; }
public DateTime content { get; set; }
public bool rich()
{
if (this.money <3000)
return false;
else
return true;
}
public void earn(GuestBook b)
{
this.money += b.money;
}
}
the function rich() and earn() is only use for this module(GuestBook)
if i didn't put it in this module , then where i should put?
Following good OOP design principles, the only way to really protect your classes' invariants (and not have a maintainability nightmare) is by not allowing them to be changed by anyone other than the class. Typically this is done by NOT exposing public setter methods (public auto properties are evil), making your fields readonly (wherever possible), and initializing them from the constructor.
The whole point of having classes is to group data with behavior. A simple data structure containing ints and strings is not a class in the OOP sense, it's just a struct.
In some cases you are stuck with an even more evil ORM that FORCES you to make all properties public. This is not an issue with Entity Framework (and some others too) though, EF can magically reflect in and access private setters if needed, you just gotta make sure there's also a private default constructor.
According to your class rich method is validating and earn method is applying business logic. You can create AdditionalMetadataAttribute for rich method logic that can fire on ModelState.IsValid and for earn method you need to create BO class that apply your all business logic.
here a link for AdditionalMetadataAttribute
I was trying to find a clear and simple example of what an anemic domain really means. There is a lot of theory around, and also many well answered questions. Still, I could not get a clear picture about to what extent "anemic domain" meaning really goes. Therefore, I believe it would be simpler to see a dummy practical example of an anemic domain design and than ask you how could this be evolved to a domain driven one...
So, let's say we have a data entity of type TaskData:
public class TaskData
{
public Guid InternalId { get; set; }
public string Title { get; set; }
public string Details { get; set; }
public TaskState ExplicitState { get; set; }
public IEnumerable<TaskData> InnerTasks { get; set; }
}
And there is the need of an additional property called "ActualState", which is a computed state: if the Task has inner sub-tasks, the value strictly depends of the children, otherwise, the "ActualState" is equal to "ExplicitState"
If I write this logic in a separate service class (I call them "engines") we have:
internal class TaskStateCalculator
{
public TaskState GetState(TaskData taskData)
{
if (taskData.InnerTasks.Any())
{
if (taskData.InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (taskData.InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
return taskData.ExplicitState;
}
}
The first question is:
Does the code above reflect an anemic domain design, even if the TaskStateCalculator service/engine is part of my Domain Layer?
If yes, in order to avoid it, we'll need to move the logic inside the TaskData class (and rename TaskData to Task). Am I right?
The second question is (actually a chain of them):
What if we have a more difficult situation? Let's say there is the need for a property called ComputeSomething inside Task entity, and the logic of this property needs to access the entire Task's repository. In this case, the Task class would have a dependency on TaskRepository. Would this be ok? How would EF construct an instance of such class? What is the alternative?
I was trying to find a clear and simple example of what an anemic domain really means
It's in fact really easy to go from an anemic domain model to a rich one.
Set all property setters to private and then add methods if you want to change state of a model.
Evaluate all Law of Demeter violations and add methods where suitable.
Eventually you will have a correct model.
In your case I would encapsulate that logic inside TaskData as your TaskStateCalculator violate Law of Demeter
public class TaskData
{
public Guid InternalId { get; private set; }
public string Title { get; private set; }
public string Details { get; private set; }
public TaskState ExplicitState { get; private set; }
public IEnumerable<TaskData> InnerTasks { get; private set; }
public TaskState GetState()
{
if (!InnerTasks.Any())
return ExplicitState;
if (InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
}
another thing is that I would probably not expose InnerTasks collection at all to the outside world (just have it as a member field). But it's hard to say as I do not know how the class is used in other scenarios.
Why private setters
Every time you have to change more than one property it's often better to describe the behavior with a method, as it's then impossible to forget to change all required properties. A method also describes better what you are trying to do than changing a set of properties.
Even if you just change a single property, that property can set the class in an invalid state as the change may not be compatible with the rest of the information in the class. Don't forget that encapsulation is one of the core principles in OOP
For example, I have the following code defined in assembly A:
public abstract class Message
{
public int ID { get; internal set; }
public Message Parent { get; internal set; }
}
From assembly B, I need to do the following:
instanceOfMessage.ID = MethodToGetUniqueIDNumber();
instanceOfMessage.Parent = MethodToGetParent(); // Returns null /w no parent
Currently, I'm using the InternalsVisibleTo compiler option to get around this:
[assembly:InternalsVisibleTo ("AssemblyB")]
// Namespace stuff here
public class Message
{
public int ID { get; internal set; }
}
It kind of feels yicky having to mess with a compiler option to make this work. So, my questions are:
Is it okay to use InternalsVisibleTo in this situation?
Should I just make the property(s) public and hope no one changes anything?
Should I even be doing this at all?
My end goal is that someone, likely just my team and I, should be able to use a Message, but enforce that properties like ID never get changed from outside the classes that manage them. However, we still need to be the ones to create the instances of the messages and such.
My end goal is that my team and I should be able to inherit from Message in a third assembly, Assembly C. Assembly C only knows about Assembly A. Assembly B gets dynamically loaded later on. C will use interfaces provided by A to send messages to B.
My end goal is that someone, likely just my team and I, should be able to use a Message, but enforce that properties like ID never get changed from outside the classes that manage them. However, we still need to be the ones to create the instances of the messages and such.
One common approach in this type of situation would be to actually use an interface for the message, and then implement the interface within AssemblyB.
This allows your messages to be created, but not modified later, as you can still have full control over the implementation.
public interface IMessage
{
int ID { get; }
IMessage Parent { get; }
}
Then your other assembly can just implement this with a private class, and return the appropriate message, without fear of it being able to be modified.
Why not just use private set and define the ID and Parent when you call the constructor?
public class Message
{
public Message(int id, Message parent) // Message constructor taking in ID and parent from external
{
ID = id;
Parent = parent;
}
public int ID { get; private set; }
public Message Parent { get; private set; }
}
This call below from outside your Message class.
Message instanceOfMessage = new Message(MethodToGetUniqueIDNumber(), MethodToGetParent());
I would probably go one step further and create a static factory method:
public class Message
{
public static Message CreateInstance(int id, Message parent)
{
// Add code here to check security of caller
return new Message(id, parent);
}
private Message(int id, Message parent)
{
ID = id;
Parent = parent;
}
public int ID { get; private set; }
public Message Parent { get; private set; }
}
To create an instance of the message you would now call:
Message instanceOfMessage = Message.CreateInstance(MethodToGetUniqueIDNumber(), MethodToGetParent());
Now I can complelty control the creation of an instance of the object, and once created it can not be modified.
Below is the class with a property.
public class abc
{
public int MyProperty { get; private set; }
}
Confusion - What's the benefit of typing private access modifier in setter ?
Simply, it's a property that the class itself is allowed to set, but external objects can only read. Perhaps MyProperty changes as a side effect to a method, perhaps it is only set once (in a constructor). The main point is the source of change with MyProperty has to come from within abc (or a nested class of abc), not from something outside that holds a reference to it.
As for why you might use it, perhaps outside code cannot be trusted to set this value. The class isn't strictly immutable, it can change, but the only code trusted to do it exists inside the class (or a nested class). The outside world can simply read.
The private modifier allows the property to be read-only in the context of public, protected, or internal access, while giving the type itself the ability to set the property (i.e., in the context of private access).
There are a couple reasons to use private set.
1) If you are not using a backing field at all and want a read-only automatic property:
public class abc
{
public int MyProperty { get; private set; }
}
2) If you want to do extra work when you modify the variable inside your class and want to capture that in a single location:
private string _name = string.Empty;
public string Name
{
get { return _name; }
private set
{
TextInfo txtInfo = Thread.CurrentThread.CurrentCulture.TextInfo;
_name = txtInfo.ToTitleCase(value);
}
}
In general, though, it's a matter of personal preference. Far as I know, there are no performance reasons to use one over the other.
This is done to make your property read-only so that the external world is not allowed to change the value of the property and only the class implementing the property can change the property value being the owner of the property.
As an example of how a class tracks its instance count and the instance count only can be increased/decreased from inside the class and the external world should not be allowed to change the instance count property e.g.:
public class Customer
{
public Customer()
{
InstanceCount++;
}
//Helps retrieving the total number of Customers
public int InstanceCount { get; private set; } //Count should not be increased by the clients of this class rather should be increased in the constructor only
}
Another benefit in some situations is, after giving a private set to your property you can give a Set method for changing the property value from external world when you want to do some calculations or validations on the value received (which is not a best practice to do inside the Set property accessors), and then change the value of the property as follows:
public class Customer
{
public string City { get; private set; }
public bool SetCity(string customerCity)
{
//validate that the customerCity is a valid USA city or else throw some business rule exception, and then call below code
City = customerCity
}
}
The private setter allows the property to only be set internally to the class, while the getter still exposes the property value publicly.
Consider following code
public class City
{
public string Name { get { return "New York"; } }
Building empEstate;
Building nyTimes;
public void Init()
{
// I hate passing "this" to all object
empEstate = new EmpEstate(this);
setSomeProperty(empEstate);
// any one can create new object of some other city
// and pass to the building
nyTimes = new NYTimes(this);
...
other = new OtherBuildings(this)
}
public void PrintAddresses()
{
empEstate.Print();
nyTimes.Print();
...
other.Print();
}
}
public abstract class Building {
City _city;
public Building(City city){
this._city = city;
}
public abstract string Name { get;}
public void Print(){
Console.WriteLine(this.Name);
Console.Write(",");
Console.WriteLine(this._city.Name);
}
}
First thing I want better solution to this approach. Print is just an example. Actually each building object raise some event to City object. I don't want to add handler to each building as there could be several buildings in city. Also I do not want to add each of them into list, as it is two task for each building (one initialization and second add to list, one forget to add to list when writing new building). For this, I want caller to be automatically available to callee, like Parent property of control (though it was added to this.Controls)
Using memory, can we know who is the parent of current object. How does GC knows that object is not being referenced (including creator). Can't we create a method (safe or unsafe) using memory to identify the caller object. I see we can use StackTrace to see the call hirarchy, can we intercept here when a new object is being created.
Building factory on city solved my problem of passing this to each object
public interface ICity
{
string Name { get; }
}
public abstract class City : ICity
{
public T CreateBuilding<T>()
{
T buildingInstance = Activator.CreateInstance<T>();
((IBuilding)buildingInstance).SetCity(this);
return buildingInstance;
}
public abstract string Name { get; }
}
interface IBuilding
{
ICity City { get; }
void SetCity(ICity city);
}
public abstract class Building : IBuilding
{
private ICity _city;
public ICity City { get { return _city; } }
public void IBuilding.SetCity(ICity city)
{
this._city = city;
}
public abstract string Name { get; }
public void Print()
{
Console.WriteLine(this.Name);
Console.Write(",");
Console.WriteLine(this._city.Name);
}
}
public class EmpEstate : Building
{
public override string Name { get { return "Emp State"; } }
}
public class NYTimes : Building
{
public override string Name { get { return "NY Times"; } }
}
public class NewYorkCity : City
{
public override string Name { get { return "New York"; } }
EmpEstate empEstate;
NYTimes nyTimes;
public void Init()
{
// Now I dont need to pass this
empEstate = this.CreateBuilding<EmpEstate>();
setSomeProperty(empEstate);
// now any one cannot create building in new your and
// say it belongs to Philedelphia :)
nyTimes = this.CreateBuilding<NYTimes>();
}
public void PrintAddresses()
{
empEstate.Print();
nyTimes.Print();
}
}
Problem was there were several classes already created and for new functionality we needed the creator object in the base class of Building Object. We did not wanted to modify the constructor of each class and pass this object to each. And City class (in example) was basically code on plugin side, so allowing them to pass city (if plugin developer pass wrong city) may disturb the functionality of entire app. So modifying the plugin base solved my purpose. Suggestions are welcome.
There is no logical "owner" of an object. Inspecting the stack trace is... not usually ideal. By comparison to Parent, that is not very different to your existing approach - merely that is set via methods/properties rather than in the constructor.
If the city is only necessary for the context of methods like Print, why not pass it in as a parameter, i.e. nyTimes.Print(this) etc. If you might need other values, rather than taking lots of parameters, consider using some kind of context object that has a city - i.e.
class PrintContext {
public City City {get;private set;}
// other stuff...
public PrintContext(City city/*, other stuff...*/) {
City = city;
}
}
I think you are misusing the terms parent and creator. The object that created the instance has no special relationship with the instance (e.g. factories create objects, but do not maintain references to them), so, in general, there is no way to find out who or what created a concrete instance.
In the same sense, parent has no meaning on a general object. We can somehow infer that the Form is parent to the TextBox, but that is not a special relationship. It this case it just means that the TextBox is in the form's Contols collection, and that it's Parent is set to the Form.
You are right that this could potentially lead to inconsistencies (Form1 thinks that TextBox is it's child, but the TextBox thinks that it's Parent is Form2), but I do not know of, and don't think there is a better solution of this kind of relationship than the Children collection / Parent reference.
Picking a few of your many questions:
I hate passing this
Why? You are telling the building which city it belongs to. How else could you do this. I see that as a common idiom for wiring objects together.
Also I do not want to add each of them into list, as it is two task
for each building (one initialization and second add to list, one
forget to add to list when writing new building).
I'm not clear what list you want to add them to, but your concern about "forgetting" is overcome if you do the work in the base constructor:
public Building(City city){
this._city = city;
// add the building to the list here - nothing to "forget"
}
As for GC, once a creator has created something there is no relationship between them unless you choose to retain a reference. You have done that with
empEstate = new EmpEstate(this);
so as long as the City is not a candidate for garbage collectio then the EmpState won't be either.