Im trying to write a simple code to implement the Singleton and object null patterns.
the code should check if the new customer has a name, if yes put it in the real customer, and if not in the fakecustomer.
My focus in this question is: Is the Singleton pattern making my code thread safe in this case?
interface Icustomer
{
string Name { get; }
bool IsNull { get; }
}
class realcustomer : Icustomer
{
public string Name { get; set; }
public bool IsNull { get { return false; } }
public realcustomer(string name)
{
Name = name;
}
}
class fakecustomer : Icustomer
{
public string Name { get { return "customer not available"; } }
public bool IsNull { get { return true; } }
}
class checkifnull
{
public static Icustomer Getcustomer(string name)
{
if (string.IsNullOrEmpty(name))
{
return new fakecustomer();
}
else
{
return new realcustomer(name);
}
}
}
class Singleton
{
private int total = 0;
private static Icustomer cust;
private Singleton() { }
public static Icustomer makecust(string name)
{
if (cust == null)
{
if (string.IsNullOrEmpty(name))
{
cust = new fakecustomer();
}
else
{
cust = new realcustomer(name);
}
}
return cust;
}
public void add()
{
total++;
}
public int getTotal()
{
return total;
}
}
internal class Program
{
static void Main(string[] args)
{
Icustomer new_cust = Singleton.makecust("name");
}
}
each pattern works when implemented on its own, but now i'm trying to use both at the same time.
Below are my classes
public class CommonClassSource
{
public int Id {get;set;}
}
public class CommonClassDestination
{
public int Id {get;set;}
}
public class SourceClass
{
public CommonClassSource CommonSource {get;set;}
}
public class DestinationClass
{
public CommonClassDestination CommonDestination {get;set;}
}
Is there any way to add null-checking in config.Bind? For example: here, check if source.CommonSource is null
TinyMapper.Bind<SourceClass, DestinationClass>(config => {
config.Bind(source => source.CommonSource.Id,
target => target.CommonDestination.Id));
});
If all you wanted to have the case handled that it there isn't an issue when source.CommonSource is null, the following script should work for you.
static bool isSourceNull;
public static void Main()
{
Func<SourceClass,object> getSCI = GetSourceClassId;
Func<DestinationClass, object> getDCI = GetDestClassId;
TinyMapper.Bind<SourceClass, DestinationClass>(config => {
config.Bind(source=>getSCI,
target =>getDCI);
});
}
static object GetSourceClassId(SourceClass source)
{
isSourceNull = source.CommonSource == null;
if (isSourceNull) return -1;
else return source.CommonSource.Id;
}
static object GetDestClassId(DestinationClass destinationClass)
{
if (isSourceNull)
{
destinationClass.CommonDestination = null;
return -1;
}
else if (destinationClass.CommonDestination != null)
return destinationClass.CommonDestination.Id;
else return -1;
}
For our project, we would like to use ViewModels.
So we decided to create ViewModels for every object we can have :
So the ViewModel looks like this (GroupVM) :
public class GroupVM : EORTCViewModel<Prisma.BO.Group>
{
public GroupVM(Prisma.BO.Group group) : base(group) { }
public string Name
{
get
{
return this._Model.Name;
}
}
public string ShortName
{
get
{
return this._Model.ShortName;
}
}
public int Id
{
get
{
return this._Model.Id;
}
}
[ScriptIgnore]
public ICollection<StudyGroupVM> StudyGroups
{
get
{
return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.StudyGroup>.ToViewModel<StudyGroupVM>(this._Model.StudyGroups);
}
}
}
The StudyVM :
public class StudyVM : EORTCViewModel<Prisma.BO.Study>
{
public StudyVM(Prisma.BO.Study study) : base(study) { }
public string Number
{
get
{
return this._Model.Number;
}
}
[ScriptIgnore]
public ICollection<StudyGroupVM> StudyGroups
{
get
{
return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.StudyGroup>.ToViewModel<StudyGroupVM>(this._Model.StudyGroups);
}
}
}
and the intermediate object (StudyGroup) :
public class StudyGroupVM : EORTCViewModel<Prisma.BO.StudyGroup>
{
public StudyGroupVM(Prisma.BO.StudyGroup studyGroup) : base(studyGroup) { }
public StudyVM Study
{
get
{
return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.Study>.ToViewModel<StudyVM>(this._Model.Study);
}
}
public GroupVM Group
{
get
{
return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.Group>.ToViewModel<GroupVM>(this._Model.Group);
}
}
}
We would like to use a factory that would create ViewModels for every navigation properties.
So we wrote a generic ViewModel factory as follow :
public static class ViewModelFactory<T> where T : IEORTCObject
{
public static R ToViewModel<R>(T model) where R : EORTCViewModel<T>
{
return (R)Activator.CreateInstance(typeof(R), new object[] { model });
}
public static ICollection<R> ToViewModel<R>(ICollection<T> models) where R : EORTCViewModel<T>
{
ICollection<R> viewModels = new List<R>();
foreach (T model in models)
{
viewModels.Add((R)Activator.CreateInstance(typeof(R), new object[] { model }));
}
return viewModels;
}
}
The problem is that when we try to access the StudyGroups property from one of the end object of the relation, it creates correctly the object but then want to recreate the same object because it seems it tries to access the getter for the other end of the relation.
This cause a StackOverFlowException since it never stops (cycles).
Does any of you have any idea how I can solve this issue ?
Can you use memoization to cache your viemodel after it has been created once?
Something like:
public GroupVM Group
{
get
{
if(groupVM == null)
{
groupVM = Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.Group>.ToViewModel<GroupVM>(this._Model.Group);
}
return groupVM;
}
}
Let me explain my question by posing a hypothetical situation. Lets start with a class:
public class PaymentDetails
{
public int Id {get;set;}
public string Status {get;set;}
}
And then I have another class:
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public PaymentDetails MyPaymentDetails{ get { return _paymentDetails; } }
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
OK, so I have these two classes. PaymentHelper has made the property MyPaymentDetails read-only.
So I cannot instantiate PaymentHelper and modify MyPaymentDetails like this:
PaymentHelper ph = new PaymentHelper();
ph.MyPaymentDetails = new PaymentDetails(); // Not allowed!!!
But I can modify the public properties inside of ph.MyPaymentDetails like this:
ph.MyPaymentDetails.Status = "Some status"; // This is allowed
How do I prevent that from working? Or is there no good way of doing that?
A property may apply access modifiers to individual accessors, for instance:
public string Status { get; private set; }
The scope of access is left to your circumstance. Keeping it private, I'm sure you can tell, will mean only elements within the scope of the current class can use the setter, protected would allow inheritors to use it, etc.
Obviously your classes need to be engineered properly from the bottom up, so as to account for appropriate scoping and robust management when used further up the hierarchy.
The idea of protecting the properties of a complex type that is itself a property isn't available from a language construct at that level.
One option is to design the contained type in such a way as to make its properties read-only using the access modifiers (public set, protected set, private set, etc).
My preference is to expose it as an interface to public consumers:
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public IPaymentDetails MyPaymentDetails{ get { return _paymentDetails; } }
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
interface IPaymentDetails
{
int Status { get; }
}
Code inside the PaymentHelper class can then use the PaymentDetails class directly, and code outside the class won't be able to use PaymentDetails unless they cast directly to it, which you can stop if you don't release the PaymentDetails class and only provide the interface.
Of course, you can never really stop the determined person who may use reflection to set things. I tend to let these people break the code :-)
Another solution is not to expose the PaymentDetails object directly, but rather wrap the properties you wish to expose. For example:
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public string PaymentDetailsStatus { get { return _paymentDetails.Status; } }
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
Edit: You could always let the behavior of value types take care of this for you. Change PaymentDetails to a struct instead of a class:
public struct PaymentDetails
{
public int Id { get; set; }
public string Status { get; set; }
}
public class PaymentHelper
{
public PaymentDetails Details { get; set; }
}
If you then try to
ph.Details.Status = "Some status"; //
You'll get a compiler error telling you that you can't do this. Since value types are returned, well, by value, you can't modify the .Status property.
Or...
If PaymentDetails and PaymentHelper are declared in the same class library (separate from the code you want to prevent from writing to the .MyPaymentDetails property, you could use:
public class PaymentDetails
{
public int Id { get; internal set; }
public string Status { get; internal set; }
}
public class PaymentHelper
{
public PaymentDetails Details { get; private set; }
}
which will prevent anything declared outside of that class library from writing to .Id or .Status.
Or, force access to .Id and .Status to go through the helper class instead of allowing read access to a .Details property:
public class PaymentHelper
{
private PaymentDetails _details;
public string Id { get { return _details.Id; } private set { _details.Id=value; } }
public string Status { get { return _details.Status; } private set { _details.Status = value; } }
}
Of course, if you're going to do that, you could just
public calss PaymentDetails
{
public int Id { get; protected set; }
public string Status { get; protected set; }
}
public class PaymentHelper : PaymentDetails
{
}
... assuming that this sort of inheritance fits with the rest of your architecture.
Or, just to illustrate the interface suggestion proposed by #MrDisappointment
public interface IDetails
{
int Id { get; }
string Status { get; }
}
public class PaymentDetails : IDetails
{
public int Id { get; private set; }
public string Status { get; private set; }
}
public class PaymentHelper
{
private PaymentDetails _details;
public IDetails Details { get { return _details; } private set { _details = value; } }
}
So there are two ways that I can think of to deal with this. One is really simple:
public class PaymentDetails
{
private int _id;
private bool _idSet = false;
int Id
{
get
{
return _id;
}
set
{
if (_idSet == false)
{
_id = value;
_idSet == true;
}
else
{
throw new ArgumentException("Cannot change an already set value.");
}
}
}
private string _status;
private bool _statusSet = false;
string Status
{
get
{
return _status;
}
set
{
if (_statusSet == false)
{
_status = value;
_statusSet = true;
}
else
{
throw new ArgumentException("Cannot change an already set value.");
}
}
}
The simple solution only allows values to be set once. Changing anything requires creating a new instance of the class.
The other is rather complex but very versatile:
public interface IPaymentDetails : IEquatable<IPaymentDetails>
{
int Id { get; }
string Status { get; }
}
public class PaymentDetails : IPaymentDetails, IEquatable<IPaymentDetails>
{
public PaymentDetails()
{
}
public PaymentDetails(IPaymentDetails paymentDetails)
{
Id = paymentDetails.Id;
Status = paymentDetails.Status;
}
public static implicit operator PaymentDetails(PaymentDetailsRO paymentDetailsRO)
{
PaymentDetails paymentDetails = new PaymentDetails(paymentDetailsRO);
return paymentDetails;
}
public override int GetHashCode()
{
return Id.GetHashCode() ^ Status.GetHashCode();
}
public bool Equals(IPaymentDetails other)
{
if (other == null)
{
return false;
}
if (this.Id == other.Id && this.Status == other.Status)
{
return true;
}
else
{
return false;
}
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return base.Equals(obj);
}
IPaymentDetails iPaymentDetailsobj = obj as IPaymentDetails;
if (iPaymentDetailsobj == null)
{
return false;
}
else
{
return Equals(iPaymentDetailsobj);
}
}
public static bool operator == (PaymentDetails paymentDetails1, PaymentDetails paymentDetails2)
{
if ((object)paymentDetails1 == null || ((object)paymentDetails2) == null)
{
return Object.Equals(paymentDetails1, paymentDetails2);
}
return paymentDetails1.Equals(paymentDetails2);
}
public static bool operator != (PaymentDetails paymentDetails1, PaymentDetails paymentDetails2)
{
if (paymentDetails1 == null || paymentDetails2 == null)
{
return ! Object.Equals(paymentDetails1, paymentDetails2);
}
return ! (paymentDetails1.Equals(paymentDetails2));
}
public int Id { get; set; }
public string Status { get; set; }
}
public class PaymentDetailsRO : IPaymentDetails, IEquatable<IPaymentDetails>
{
public PaymentDetailsRO()
{
}
public PaymentDetailsRO(IPaymentDetails paymentDetails)
{
Id = paymentDetails.Id;
Status = paymentDetails.Status;
}
public static implicit operator PaymentDetailsRO(PaymentDetails paymentDetails)
{
PaymentDetailsRO paymentDetailsRO = new PaymentDetailsRO(paymentDetails);
return paymentDetailsRO;
}
public override int GetHashCode()
{
return Id.GetHashCode() ^ Status.GetHashCode();
}
public bool Equals(IPaymentDetails other)
{
if (other == null)
{
return false;
}
if (this.Id == other.Id && this.Status == other.Status)
{
return true;
}
else
{
return false;
}
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return base.Equals(obj);
}
IPaymentDetails iPaymentDetailsobj = obj as IPaymentDetails;
if (iPaymentDetailsobj == null)
{
return false;
}
else
{
return Equals(iPaymentDetailsobj);
}
}
public static bool operator == (PaymentDetailsRO paymentDetailsRO1, PaymentDetailsRO paymentDetailsRO2)
{
if ((object)paymentDetailsRO1 == null || ((object)paymentDetailsRO2) == null)
{
return Object.Equals(paymentDetailsRO1, paymentDetailsRO2);
}
return paymentDetailsRO1.Equals(paymentDetailsRO2);
}
public static bool operator != (PaymentDetailsRO paymentDetailsRO1, PaymentDetailsRO paymentDetailsRO2)
{
if (paymentDetailsRO1 == null || paymentDetailsRO2 == null)
{
return ! Object.Equals(paymentDetailsRO1, paymentDetailsRO2);
}
return ! (paymentDetailsRO1.Equals(paymentDetailsRO2));
}
public int Id { get; private set; }
public string Status { get; private set;}
}
public class PaymentHelper
{
private PaymentDetails _paymentDetails;
public PaymentDetailsRO MyPaymentDetails
{
get
{
return _paymentDetails;
}
}
public PaymentHelper()
{
_paymentDetails = new PaymentDetails();
}
public void ModifyPaymentDetails(string someString)
{
// code to take the arguments and modify this._paymentDetails
}
}
The complex solution allows a changeable backing store, but presents a readonly version to the consumer that cannot be changed by outsiders to your helper class.
Note that both patterns only work if you implement them all the way down the object graph or stick to value types and strings.
You can't prevent that, the property returns a refrence to a PaymentDetails, and once somebody has that, it is out of your control.
However, you can just wrap the PaymentDetails. Instead of returning it verbatim, offer only getters for its public properties.
You can also assign access modifiers for the PaymentDetails class like so:
public string Status { get; private set; }
if you don't need the class elsewhere with a public setter.
Yet another solution: Make setters internal
This is the pragmatical way if the PaymentHelper is in the same assembly of PaymentDetails and the clients of PaymentHelper are in another assembly.
Yet another solution: Delegate from PaymentHelper to PaymentDetails.
This is to add the same properties to PaymentHelper as in PaymentDetails.
If you have many properties you can let generate the delegating properties into PaymentHelper by ReSharper. Place cursor on *_paymentDetails* of line
private PaymentDetails _paymentDetails;
Press Alt+Insert->Delegating Members. Then all PaymentHelper properties delegate to PaymentDetails properties.
I am having a piece of code in which i delegate certain properties of a class to another class if the class exists. Below you see the start time being defined on the TimeProvider if it exists.
public override DateTime StartTime
{
get
{
return (TimeProvider != null) ? TimeProvider.StartTime : base.StartTime;
}
set
{
if (TimeProvider != null)
{
TimeProvider.StartTime = value;
}
else
{
base.StartTime = value;
}
}
}
Now my 'problem' is that i have a lot more properties (like endtime,currentime) i delegate to the TimeProvider if it is not null. So i would like to have code like:
public override DateTime StartTime
{
get
{
return GetTime(()=>StartTime);
}
set
{
SetTime(()=>StartTime)
}
}
Where the ()=>StartTime expression is sometimes 'evaluated' on the TimeProvider and sometimes on the class itself (they share a baseclass). Can something like this be done? Preferably without using reflection.
Cake
public class Foo
{
private string _string1;
public Foo foo { get; set; }
private T GetProperty<T>(Func<Foo,T> getter)
{
return foo == null
? getter(this)
: getter(foo);
}
private void SetProperty(Action<Foo> setter)
{
if (foo == null)
setter(this);
else
setter(foo);
}
public string String1
{
get { return GetProperty(a => a._string1); }
set { SetProperty(a => a._string1 = value); }
}
}