I have a colleciton of objects which need to maintain several time-stamps for that last time certain properties within the object was updated (one time-stamp per property).
I would just implement the time-stamp update in the setter except that the deserialization library being used first creates an object, then updates all of its properties (using the object's setter). This means that all my time-stamps would be invalidated every time my program deserializes them.
I'm thinking I need a singleton class or some update method which handles updating the properties and also controls the time-stamp update. Is there a better way to implement this behavior? Does a design pattern exist for this behavior?
If you separate your serialization concerns from your business layer, it should help find you some flexibility to hammer out a solution. Have 99% of your API work with your business object (which updates timestamps when properties update), then only convert to/from some data-transfer-object (DTO) for serialization purposes only.
For example, given some business object like this:
public class MyObject
{
public DateTime SomeValueUpdated { get; private set; }
private double _SomeValue;
public double SomeValue
{
get
{
return _SomeValue;
}
set
{
SomeValueUpdated = DateTime.Now;
_SomeValue = value;
}
}
public MyObject()
{
}
//for deserialization purposes only
public MyObject(double someValue, DateTime someValueUpdated)
{
this.SomeValue = someValue;
this.SomeValueUpdated = someValueUpdated;
}
}
You could have a matching DTO like this:
public class MyObjectDTO
{
public DateTime SomeValueUpdated { get; set; }
public double SomeValue { get; set; }
}
Your DTO can be specially adorned with various XML schema altering attributes, or you can manage the timestamps however you see fit and your business layer doesn't know and doesn't care.
When it comes time to serialize or deserialize the objects, run them through a converter utility:
public static class MyObjectDTOConverter
{
public static MyObjectDTO ToSerializable(MyObject myObj)
{
return new MyObjectDTO {
SomeValue = myObj.SomeValue,
SomeValueUpdated = myObj.SomeValueUpdated
};
}
public static MyObject FromSerializable(MyObjectDTO myObjSerialized)
{
return new MyObject(
myObjSerialized.SomeValue,
myObjSerialized.SomeValueUpdated
);
}
}
If you wish, you can make any of the properties or constructors of MyObject to be internal so only your conversion utility can access them. (For example, maybe you don't want to have the public MyObject(double someValue, DateTime someValueUpdated) constructor publicly accessible)
Related
I've a class with some properties which I want to serialize. My problem is that
I can't serialize the "CustomCanvasClass". I only need the X/Y properties of it.
So I created a new property and marked the "CustomCanvasClass" property as [NonSerialized].
Unfortunatly it won't works. Maybe have somebody another idea to copy this data out of the class.
[Serializable]
public class CustomClass
{
//won't serialized
public double X
{
get
{
return Canvas.GetLeft(CustomCanvasClass);
}
set
{
Canvas.SetLeft(CustomCanvasClass, value);
}
}
public string Property1 { get; set; }
//CanvasElement inherits from Canvas. Serialization would throw a Exception.
public CanvasElement CustomCanvasClass
{
get
{
return _CustomCanvasClass;
}
set
{
_CustomCanvasClass = value;
}
}
[NonSerialized]
private CanvasElement _CustomCanvasClass;
}
Use a DTO for the properties you need and serialize that.
DTO stands for data transfer object. It contains data you want to transfer only and no logic.
E.g. Add a class like this:
class MyCustomClassDto
{
public double X {get;set;}
public double Y {get;set;}
}
So instead of trying to serialize your custom class directly, you would initialize an instance of this with your X and Y values and serialize that.
Then in your main class you could add this:
public MyCustomClassDto GetData()
{
return new MyCustomerClassDto{X = X, Y = Y};
}
You could add a serialization method to your DTO also.
Alternatively you can use a mapping tool like automapper - which would be suitable if you have many DTOs or corresponding objects in different layers.
Hope that makes the idea clear. Can't see other ways of expanding without seeing more details/context.
The proper mvvm itemspanel approach in the comment on the question is preferable, but it might require substantial rewriting depending on your existing codebase. You might want to consider the business case for such refactoring imo, considering the effort against how much more is likely to be built on top of it.
I have a summary objects, who's responsibilities actually to combine a lot of things together and create a summary report, who later going to be serialized into the XML.
In this objects I have a lot of structures like this:
public class SummaryVisit : Visit, IMappable
{
public int SummaryId { get; set; }
public int PatientId { get; set; }
public int LocationId { get; set; }
public IMappable Patient
{
get
{
return new SummaryPatient(PatientBusinessService.FindPatient(this.PatientId));
}
}
public IMappable Location
{
get
{
return new SummaryLocation(LocationBusinessService.FindLocation(this.LocationId));
}
}
public IEnumerable<IMappable> Comments
{
get
{
return new SummaryComments(CommentBusinessService.FindComments(this.SummaryId, Location));
}
}
// ... can be a lot of these structures
// ... using different business services and summary objects
public IEnumerable<IMappable> Tasks
{
get
{
return new SummaryTasks(TaskBusinessService.FindTasks(this));
}
}
}
PatientBusinessService, LocationBusinessService etc. are statics.
And each of these SummaryPatient, SummaryLocation etc. have the same type of structure inside.
What is the best approach to refactor and unit test this?
Tried to replace static calls with calls via the interfaced proxies (or refactor statics to non-static classes & interfaces), but this class just got a lot of these interfaces as the constructor injection stuff and start to be super greedy. In addition, these interfaces have a one used method inside (if I going to create it just to this summary needs).
And as soon as this is a summary object, commonly this static services used just once for the whole structure to get appropriate properties for output.
You could change your tests to be more integrational (test more than one class at the time). You could try to modify your services to be more universal and be able to take data from different sources (like TestDataProvider and your current data provider).
Better solution I think is to modify classes you want to test:
Use strong typing for properties and gain all benefits. I think you should return more specific types instead of IMappable
It looks like some of your data is stored inside class (ids) some data is not (IMappable object references). I would refactor this to hold references to objects inside class:
private SummaryPatient _patient;
public SummaryPatient Patient
{
get
{
if (_patient == null)
_patient = new SummaryPatient(PatientBusinessService.FindPatient(this.PatientId));
return _patient;
}
}
Then you can assign your tests data in constructor or create static method CreateDummy(...) just for unit tests. This method then should use CreateDummy for child objects. You can use it in your unit tests.
Foreword: this is a long question and if you don't want to read and understand why I'm asking it then please spare the comment "why not simply test the code?"
I have an object model that looks somewhat like this:
public class MyObjectModel
{
public byte TypeOfNestedObject { get; set; }
public string NestedObjectInJson { get; set; }
public NestedObjectModel1 { get; set; }
public NestedObjectModel2 { get; set; }
public NestedObjectModel3 { get; set; }
public MyObjectModel()
{
NestedObjectModel1 = null;
NestedObjectModel2 = null;
NestedObjectModel3 = null;
}
public void DeserializeJsonString()
{
if (TypeOfNestedObject == 1) {
NestedObjectModel1 = "deserialize NestedObjectInJson
into NestedObjectModel1";
}
if (TypeOfNestedObject == 2) {
NestedObjectModel2 = "deserialize NestedObjectInJson
into NestedObjectModel2";
}
if (TypeOfNestedObject == 3) { NestedObjectModel3 ... }
}
}
Basically, the object is composed of three nested objects (NestedObjectModel1, NestedObjectModel2 and NestedObjectModel3). However, only one of them is actually used at any given time. In the database, I store fields that are used to recreate this object and one of the database fields is a json string that contains one of the three nested objects for a particular instance.
My query looks somewhat like this:
var TheObjectModel = from t in MyDC.Table
.....
select new MyObjectModel()
{
TypeOfNestedObject = t.TypeOfNestedObject,
NestedObjectInJson = t.NestedObjectInJson
};
I use the property TypeOfNestedObject to know which nested object the particular instance of MyObjectModel has. For the moment, after the the query has executed, I run a method that reads TypeOfNestedObject and deserializes the string NestedObjectInJson to the appropriate type and adds the deserialized object as the corresponding nested object.
Now I want to add a custom setter to NestedObjectInJson so that when this property is set when the query runs, the object automatically deserializes the string to the appropriate type. However, for this to work, the object would also have to have the property TypeOfNestedObject properly set. I want to write the setter like this:
public NestedObjectInJson
{
set {
if (this.TypeOfNestedObject == 1) {
NestedObjectModel1 = "deserialize NestedObjectInJson
into NestedObjectModel1 ";
}
}
}
If I write the setter like this, is the property TypeOfNestedObject needs to be available at the time the setter runs. If you notice, in the query, I load TypeOfNestedObject before I load NestedObjectInJson.
So the question is this: If I decide to remove the call to DeserializeJsonString and create this custom setter, will the property TypeOfNestedObject be available because in the query it's set before NestedObjectInJson or is the order in which the query is written make the availability of the property TypeOfNestedObject unpredictable?
This would work, the order is predictable.
However, I would advise against something like that. The clean approach would be to provide a constructor that takes the type and the JSON and performs the deserialization.
With that approach you would avoid the temporal coupling you currently have.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Since immutability is not fully baked into C# to the degree it is for F#, or fully into the framework (BCL) despite some support in the CLR, what's a fairly complete solution for (im)mutability for C#?
My order of preference is a solution consisting of general patterns/principles compatible with
a single open-source library with few dependencies
a small number of complementary/compatible open-source libraries
something commercial
that
covers Lippert's kinds of immutability
offers decent performance (that's vague I know)
supports serialization
supports cloning/copying (deep/shallow/partial?)
feels natural in scenarios such as DDD, builder patterns, configuration, and threading
provides immutable collections
I'd also like to include patterns you as the community might come up with that don't exactly fit in a framework such as expressing mutability intent through interfaces (where both clients that shouldn't change something and may want to change something can only do so through interfaces, and not the backing class (yes, I know this isn't true immutability, but sufficient):
public interface IX
{
int Y{ get; }
ReadOnlyCollection<string> Z { get; }
IMutableX Clone();
}
public interface IMutableX: IX
{
new int Y{ get; set; }
new ICollection<string> Z{ get; } // or IList<string>
}
// generally no one should get ahold of an X directly
internal class X: IMutableX
{
public int Y{ get; set; }
ICollection<string> IMutableX.Z { get { return z; } }
public ReadOnlyCollection<string> Z
{
get { return new ReadOnlyCollection<string>(z); }
}
public IMutableX Clone()
{
var c = MemberwiseClone();
c.z = new List<string>(z);
return c;
}
private IList<string> z = new List<string>();
}
// ...
public void ContriveExample(IX x)
{
if (x.Y != 3 || x.Z.Count < 10) return;
var c= x.Clone();
c.Y++;
c.Z.Clear();
c.Z.Add("Bye, off to another thread");
// ...
}
Would the better solution be to just use F# where you want true immutability?
Use this T4 template I put together to solve this problem. It should generally suit your needs for whatever kinds of immutable objects you need to create.
There's no need to go with generics or use any interfaces. For my purposes, I do not want my immutable classes to be convertible to one another. Why would you? What common traits should they share that means they should be convertible to one another? Enforcing a code pattern should be the job of a code generator (or better yet, a nice-enough type system to allow you to do define general code patterns, which C# unfortunately does not have).
Here's some example output from the template to illustrate the basic concept at play (nevermind the types used for the properties):
public sealed partial class CommitPartial
{
public CommitID ID { get; private set; }
public TreeID TreeID { get; private set; }
public string Committer { get; private set; }
public DateTimeOffset DateCommitted { get; private set; }
public string Message { get; private set; }
public CommitPartial(Builder b)
{
this.ID = b.ID;
this.TreeID = b.TreeID;
this.Committer = b.Committer;
this.DateCommitted = b.DateCommitted;
this.Message = b.Message;
}
public sealed class Builder
{
public CommitID ID { get; set; }
public TreeID TreeID { get; set; }
public string Committer { get; set; }
public DateTimeOffset DateCommitted { get; set; }
public string Message { get; set; }
public Builder() { }
public Builder(CommitPartial imm)
{
this.ID = imm.ID;
this.TreeID = imm.TreeID;
this.Committer = imm.Committer;
this.DateCommitted = imm.DateCommitted;
this.Message = imm.Message;
}
public Builder(
CommitID pID
,TreeID pTreeID
,string pCommitter
,DateTimeOffset pDateCommitted
,string pMessage
)
{
this.ID = pID;
this.TreeID = pTreeID;
this.Committer = pCommitter;
this.DateCommitted = pDateCommitted;
this.Message = pMessage;
}
}
public static implicit operator CommitPartial(Builder b)
{
return new CommitPartial(b);
}
}
The basic pattern is to have an immutable class with a nested mutable Builder class that is used to construct instances of the immutable class in a mutable way. The only way to set the immutable class's properties is to construct a ImmutableType.Builder class and set that in the normal mutable way and convert that to its containing ImmutableType class with an implicit conversion operator.
You can extend the T4 template to add a default public ctor to the ImmutableType class itself so you can avoid a double allocation if you can set all the properties up-front.
Here's an example usage:
CommitPartial cp = new CommitPartial.Builder() { Message = "Hello", OtherFields = value, ... };
or...
CommitPartial.Builder cpb = new CommitPartial.Builder();
cpb.Message = "Hello";
...
// using the implicit conversion operator:
CommitPartial cp = cpb;
// alternatively, using an explicit cast to invoke the conversion operator:
CommitPartial cp = (CommitPartial)cpb;
Note that the implicit conversion operator from CommitPartial.Builder to CommitPartial is used in the assignment. That's the part that "freezes" the mutable CommitPartial.Builder by constructing a new immutable CommitPartial instance out of it with normal copy semantics.
Personally, I'm not really aware of any third party or previous solutions to this problem, so my apologies if I'm covering old ground. But, if I were going to implement some kind of immutability standard for a project I was working on, I would start with something like this:
public interface ISnaphot<T>
{
T TakeSnapshot();
}
public class Immutable<T> where T : ISnaphot<T>
{
private readonly T _item;
public T Copy { get { return _item.TakeSnapshot(); } }
public Immutable(T item)
{
_item = item.TakeSnapshot();
}
}
This interface would be implemented something like:
public class Customer : ISnaphot<Customer>
{
public string Name { get; set; }
private List<string> _creditCardNumbers = new List<string>();
public List<string> CreditCardNumbers { get { return _creditCardNumbers; } set { _creditCardNumbers = value; } }
public Customer TakeSnapshot()
{
return new Customer() { Name = this.Name, CreditCardNumbers = new List<string>(this.CreditCardNumbers) };
}
}
And client code would be something like:
public void Example()
{
var myCustomer = new Customer() { Name = "Erik";}
var myImmutableCustomer = new Immutable<Customer>(myCustomer);
myCustomer.Name = null;
myCustomer.CreditCardNumbers = null;
//These guys do not throw exceptions
Console.WriteLine(myImmutableCustomer.Copy.Name.Length);
Console.WriteLine("Credit card count: " + myImmutableCustomer.Copy.CreditCardNumbers.Count);
}
The glaring deficiency is that the implementation is only as good as the client of ISnapshot's implementation of TakeSnapshot, but at least it would standardize things and you'd know where to go searching if you had issues related to questionable mutability. The burden would also be on potential implementors to recognize whether or not they could provide snapshot immutability and not implement the interface, if not (i.e. the class returns a reference to a field that does not support any kind of clone/copy and thus cannot be snapshot-ed).
As I said, this is a start—how I'd probably start—certainly not an optimal solution or a finished, polished idea. From here, I'd see how my usage evolved and modify this approach accordingly. But, at least here I'd know that I could define how to make something immutable and write unit tests to assure myself that it was.
I realize that this isn't far removed from just implementing an object copy, but it standardizes copy vis a vis immutability. In a code base, you might see some implementors of ICloneable, some copy constructors, and some explicit copy methods, perhaps even in the same class. Defining something like this tells you that the intention is specifically related to immutability—I want a snapshot as opposed to a duplicate object because I happen to want n more of that object. The Immtuable<T> class also centralizes the relationship between immutability and copies; if you later want to optimize somehow, like caching the snapshot until dirty, you needn't do it in all implementors of copying logic.
If the goal is to have objects which behave as unshared mutable objects, but which can be shared when doing so would improve efficiency, I would suggest having a private, mutable "fundamental data" type. Although anyone holding a reference to objects of this type would be able to mutate it, no such references would ever escape the assembly. All outside manipulations to the data must be done through wrapper objects, each of which holds two references:
UnsharedVersion--Holds the only reference in existence to its internal data object, and is free to modify it
SharedImmutableVersion--Holds a reference to the data object, to which no references exist except in other SharedImmutableVersion fields; such objects may be of a mutable type, but will in practice be immutable because no references will ever be made available to code that would mutate them.
One or both fields may be populated; when both are populated, they should refer to instances with identical data.
If an attempt is made to mutate an object via the wrapper and the UnsharedVersion field is null, a clone of the object in SharedImmutableVersion should be stored in UnsharedVersion. Next, SharedImmutableCVersion should be cleared and the object in UnsharedVersion mutated as desired.
If an attempt is made to clone an object, and SharedImmutableVersion is empty, a clone of the object in UnsharedVersion should be stored into SharedImmutableVersion. Next, a new wrapper should be constructed with its UnsharedVersion field empty and its SharedImmutableVersion field populated with the SharedImmutableVersion from the original.
It multiple clones are made of an object, whether directly or indirectly, and the object hasn't been mutated between the construction of those clones, all clones will refer to the same object instance. Any of those clones may be mutated, however, without affecting the others. Any such mutation would generate a new instance and store it in UnsharedVersion.
Bit of an odd one this...
Lets say I have the following class:
public class Wibble
{
public string Foo {get;set;}
public string Bar {get;set;}
}
This class is used a process where the values of Foo and Bar are updated/changed. However after a certain point in the process I want to "lock" the instance to prevent any changes from being made. So the question is how best to do this?
A solution of sorts would be something like this:
public class Wibble
{
private string _foo;
private string _bar;
public bool Locked {get; set;}
public string Foo
{
get
{
return this._foo
}
set
{
if (this.Locked)
{
throw new ObjectIsLockedException()
}
this._foo = value;
}
}
public string Bar
{
get
{
return this._bar
}
set
{
if (this.Locked)
{
throw new ObjectIsLockedException()
}
this._bar = value;
}
}
}
However this seems a little inelegant.
The reason for wanting to do this is that I have an application framework that uses externally developed plugins that use the class. The Wibble class is passed into the plugins however some of them should never change the contents, some of them can. The intention behind this is to catch development integration issues rather than runtime production issues. Having the object "locked" allows is to quickly identify plugins that are not coded as specified.
I've implemented something similar to your locked pattern, but also with a read-only interface implemented by a private sub-class containing the actual class data, so that you could pass out what is clearly a read-only view of the data and which can't be up-casted to the original 'mutable version'. The locking was purely to prevent the data provider from making further changes after it had provided an immutable view.
It worked reasonably well, but was a bit awkward, as you've noted. I think it's actually cleaner to have mutable 'Builder' objects which can then generate immutable snapshots. Think StringBuilder and String. This means you duplicate some property code and have to write the routines to do the copying, but it's less awkward, in my opinion, than having a write-lock on every property. It's also evident at compile-time that the snapshot is supposed to be read-only and the user of the Builder cannot modify the snapshots that it created earlier.
I would recommend this:
An immutable base class:
public class Wibble
{
public string Foo { get; private set; }
public string Bar { get; private set; }
public Wibble(string foo, string bar)
{
this.Foo = foo;
this.Bar = bar
}
}
Then a mutable class which you can change, and then create an immutable copy when the time comes.
public class MutableWibble
{
public string Foo { get; set; }
public string Bar { get; set; }
public Wibble CreateImmutableWibble()
{
return new Wibble(this.Foo, this.Bar);
}
}
I can't remember the C# syntax exactly, but you get the idea.
Further reading: http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx
You cannot make an object immutable!
You can follow this post:
How do I create an immutable Class?
But I think you can always change property values by reflection!
update
"...Actually, string objects are not that
immutable and as far as I know there are at least 2 ways to break string
immutability. With pointers as shown by this code example and with some advanced System.Reflection usage...."
http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/
The other option you have is use the BinaryFormatter to create a memberwise clone of the object to be "locked". Though you're not locking the object you're creating a snapshot which can be discarded while the original remains unchanged.