Which approach for kind of Singleton is better? - c#

My program instantiates an object with parameters passed in command line. I need to be able to instantiate an object with those parameters but yet it should be created only once. I've read these posts 1 & 2 but I still didn't understand which approach is better:
1 - var myInstance = MyClass.Instance.Create("param1", "param2");
OR
2 - var myInstance = MyClass.Instance;
myInstance.setParam1("param1");
myInstance.setParam2("param2");
In the first approach the new instance for each different pair of parameters passed to Create will be created. The only way to prevent this is to set flag inside Create that will return the created instance.
In 2nd approach the problem is what if constructor of MyClass will depend on param1 and param2?
So, what would you suggest?

You can use the first approach too:
MyClass.Instance.Create("param1", "param2")
with slight difference, which may make parameters not mandatory, if you need, using Named Parameters, like say:
MyClass.Instance.Create(param1 = "param1", param2 = "param2")
So you can avoid using parameters at all (during call) and lay on default values provided in declaration.

I'd:
create an immutable Config class with a public constructor that takes the parameters
create a static method Config ParseCommandLine(string) that turns a command-line into a Config object.
Since this is a pure function (no side-effects, no global state) it's easy to test this.
a static method Config ParseCommandLine() that gets the actual command line and calls the above method (a bit ugly, since it accesses global mutable state)
Finally use Config.SetInstance(ParseCommandLine()) to back the Instance property on your "singleton". This is a bit ugly, but using a singleton is ugly in the first place.
This "singleton" doesn't really enforce that there is a single config, but it's more of a default instance. In my experience real singletons are rarely needed, and even the default instance is kind of a hack.
You'd end up with something like this:
public class Config
{
public string Param1{get;private set;}
public int Param2(get;private set;}
public Config(string param1, int param2)
{
Param1=param1;
Param2=param2;
}
// take a string[] if you prefer to use Environment.GetCommandLineArgs
public Config ParseCommandLine(string commandLine)
{
string param1=...;
int param2=...;
return new Config(param1:param1, param2:param2);
}
public Config ParseCommandLine()
{
return ParseCommandLine(Environment.CommandLine);
}
}
I'd also consider throwing the static Instance property away, in favour of injecting the configuration to the objects that need it. But for a small program that may be over-engineering.

In your case it is better to use no Singleton.
Singleton's Intent:
Ensure that only one instance of a class is created.
Provide a global point of access to the object.
http://www.oodesign.com/singleton-pattern.html
Use a private static attribute as a flag if you need to ensure that only one instance is allowed.
Update:
public class MyClass {
private static boolean isAlreadyInitiated = false;
public MyClass() {
if(isAlreadyInitiated){
throw new IllegalStateException("Only one instance allowed.");
}
isAlreadyInitiated = true;
}
}

Related

Factory driven by enum attributes

I have a situation where a factory pattern seems appropriate like this:
enum Food {
Cake,
Cookies,
Milk,
CannedBeans
}
public static class FoodMetaDataFactory{
public static IFood GetMetaData(Food foodType){ //takes a food enum value as a parameter
switch(foodType){
case Food.Milk:
return new MilkMetaData();
case Food.CannedBeans:
return new CannedBeansMetaData();
case Food.Cookies:
return new CookiesMetaData();
case Food.Cake:
return new CakeMetaData();
}
}
}
However, I'd rather have more declarative pattern like this:
enum Food {
[FoodMetaDataAttribute(typeof(CakeMetaData))]
Cake,
[FoodMetaDataAttribute(typeof(CookiesMetaData))]
Cookies,
[FoodMetaDataAttribute(typeof(MilkMetaData))]
Milk,
[FoodMetaDataAttribute(typeof(CannedBeansMetaData))]
CannedBeans
}
public static class FoodMetaDataFactory{
public static IFood GetMetaData(Food foodType){ //takes a food enum value as a parameter
//reflectively retrieve FoodMetaDataAttribute
Type enumType = typeof(Food);
var memInfo = enumType.GetMember(foodType.ToString());
//assume one item returned
var foodMetaDataAttributes = memInfo[0].GetCustomAttributes(typeof(FoodMetaDataAttribute),
false);
// now access the property telling us the concrete type of the metadata class(this is the type passed in the attribute's declaration
Type targetType = ((FoodMetaDataAttribute)foodMetaDataAttributes[0]).MetaDataProviderType;
//not done yet, now we need to reflectively instantiate targetType, something like this
ConstructorInfo ctor = targetType.GetConstructor(new[] { });
//invoke the constructor, returning concrete instance such as CakeMetaData
return ctor.Invoke(new object[] {}) as IFood;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class FoodMetaDataAttribute : Attribute
{
public FoodMetaDataAttribute(Type metaDataProviderType){
MetaDataProviderType = metaDataProviderType;
}
public Type MetaDataProviderType { get; set; }
}
I like this because it is clear to anyone adding new values to the enum that they need a meta data class and declare it in the attribute. This IMO is better than having to remember to modify the switch case in a factory.
It seemed simple at first until I started to think about the implementation of GetMetaData that has to reflectively retrieve the attribute, the typeof parameter, and then reflectively instantiate the MetaData class. I'm not experienced in creating attribute classes, so the primary driver of this question is a hope that maybe there's a simpler way to accomplish this with attributes. If attribute classes didn't have so many restrictions, such as on using generic types, I'd have this done in a way I liked with some compile time safety.
This proposed solution has no compile time safety. You can pass in types to the attribute that don't implement IFood, which is the minimum requirement for MetaData classes such as MilkMetaData. If attributes allowed generic type parameters I'd use that instead of typeof and could apply a where T:IFood
Is there a better way to utilize attributes to accomplish this mapping from enum value to concrete class?
What I usually do in these cases is create a dictionary of factories, e.g.:
private IDictionary<MyEnum, Func<IMyInterface>> Factories = new Dictionary<MyEnum, Func<IMyInterface>> {
{ MyEnum.MyValue, () => new MyType() },
// etc.
}
Simple and easy to maintain, extend or validate. You can create instance by doing:
IMyInterface instance;
if(!Factories.TryGetValue(enumValue, out instance))
throw new Exception(string.Format("No factory for enum value {0}", enumValue));
return instance;
Note that separating the enum from the actual instance should be a good thing (split implementation from data). Otherwise, I suggest you simply pass on the actual type to a generic method.
I'm not 100% sure that there is not a completely different approach that would be better, but there is just couple things you can improve in your current code:
You can use Activator.CreateInstance(type) instead of getting the constructor:
return Activator.CreateInstance(targetType) as IFood;
You can also consider some kind of cache, to avoid doing all the reflection-related work on every single call. You can either store a single instance of concrete IFood implementation for each enum value, using simple dictionary:
public static class FoodMetaDataFactory
{
private static Dictionary<Food, IFood> _cache = new Dictionary<Food, IFood>();
public static IFood GetMetaData(Food foodType)
{ //takes a food enum value as a parameter
IFood value;
if (!_cache.TryGetValue(foodType, out value))
{
lock (_cache)
{
if (!_cache.TryGetValue(foodType, out value))
{
var enumType = typeof(Food);
var memberInfo = enumType.GetMember(foodType.ToString());
var foodMetaDataAttributes = memberInfo[0].GetCustomAttributes(typeof(FoodMetaDataAttribute), false);
var targetType = ((FoodMetaDataAttribute)foodMetaDataAttributes[0]).MetaDataProviderType;
value = Activator.CreateInstance(targetType) as IFood;
_cache.Add(foodType, value);
}
}
}
return value;
}
}
or if you need each call to return fresh instance instead of shared one, you can use Expression Trees, to generate a Func<IFood> lambda expression when GetMetaData is called for the first time for given enum value, and call it later instead of reflection-processing.
About compile-time safety: I'm afraid you'd have to write your own custom check about that, e.g. as FxCop custom rule, or maybe something using Roslyn, if you're using newest (beta) version of Visual Studio.
New here. To start from the end, If you want to use these Enum values for display, the best way to do it is to decorate them with an attribute that is a display string (or CSV), but if the values need to be complex, you should be using a Factory Method that creates new Food types. A base class can contain common values while each successive Child class has specifics that can then always be fed to the UI mechanism.
This only works if either each type creates it's own View or the views are common between types. This is similar to dependency injection in the second idea.
But if you want to add additional enums that represent code paths, you have to ALWAYS update your Controller\ViewModel unless there is some generic model that is always used for display.
I don't know your code base, so I don't know what type of refactoring would be required for a Factory or Adapter pattern.

I am having trouble assigning an Array?

I am having trouble with this piece of code and I can't figure out how to get it to work. I can't figure out what the problem is as to me it looks like it should work. The string array called m_nameList on both places are marked as 'An object reference required for the non static feild, method, or property 'Solutionname.classname.m_nameList'
the code:
public static bool CheckVacantSeats(int seatNumber)
{
if (m_nameList[seatNumber] == null)
{
return true;
}
return false;
}
m_nameList is an array that is declared in an constructor before this static bool:
public SeatManager(int maxNumberOfSeats)
{
m_totNumOfSeats = maxNumberOfSeats;
m_nameList = new string[m_totNumOfSeats];
m_priceList = new double[m_totNumOfSeats];
}
I am calling the CheckVacantSeat from another class with this:
bool validSeats = SeatManager.CheckVacantSeats(seatNumber, m_nameList);
I can't figure out what is wrong with it. So i need some help figuring out why m_nameList does not work for me?
Thanks in advance!!
//Regards
The problem is that you have marked your method as static. Since it is static, it has "no" state, and cannot access class members which are not marked as static.
You can mark m_nameList as static, but that means that it's value is shared across all reads and writes. m_nameList looks like a simple lookup table so maybe this is what you want?
Recommended reading is static and Static Classes and Static Members.
Your function is static, but your variables are not static.
Well your call is wrong for a start, your method CheckVacantSeats only accepts one parameter so you can't call it with two??!
CheckVacantSeats(int seatNumber)
SeatManager.CheckVacantSeats(seatNumber, m_nameList);
your method is also static so there's no point having a constructor.
I think what your after is:
SeatManager seatManager = new SeatManager(maxNumberOfSeats);
seatManager.CheckVacantSeats(seatNumber);
Also
public bool CheckVacantSeats(int seatNumber)
{
if (m_nameList[seatNumber] == null)
{
return true;
}
return false;
}
You are mixing two concepts: an instance initialized with a constructor, and a static class with static members. You cannot expect a static member method to access a non-static field. I guess your m_nameList field is static as well, otherwise your code wouldn't even compile. You should choose either way:
make all SeatManager's members non-static;
turn the SeatManager class into a static class having all members static.
Since you need to initialize the SeatManager with the total number of seats, the better way seems to be No. (1). Then instead of SeatManager.CheckVacantSeats() you would call an instance like mySeatManager.CheckVacantSeats(). Even in case there will always be just one instance of SeatManager — a singleton — this approach is better. With a singleton, you could end up with a public static SeatManager Instance { get; set; } property in SeatManager and work with it like this: SeatManager.Instace.CheckVacantSeats(). This is usually called a singleton pattern.

ReSharper warns: "Static field in generic type"

public class EnumRouteConstraint<T> : IRouteConstraint
where T : struct
{
private static readonly Lazy<HashSet<string>> _enumNames; // <--
static EnumRouteConstraint()
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException(
Resources.Error.EnumRouteConstraint.FormatWith(typeof(T).FullName));
}
string[] names = Enum.GetNames(typeof(T));
_enumNames = new Lazy<HashSet<string>>(() => new HashSet<string>
(
names.Select(name => name), StringComparer.InvariantCultureIgnoreCase
));
}
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
bool match = _enumNames.Value.Contains(values[parameterName].ToString());
return match;
}
}
Is this wrong? I would assume that this actually has a static readonly field for each of the possible EnumRouteConstraint<T> that I happen to instance.
It's fine to have a static field in a generic type, so long as you know that you'll really get one field per combination of type arguments. My guess is that R# is just warning you in case you weren't aware of that.
Here's an example of that:
using System;
public class Generic<T>
{
// Of course we wouldn't normally have public fields, but...
public static int Foo;
}
public class Test
{
public static void Main()
{
Generic<string>.Foo = 20;
Generic<object>.Foo = 10;
Console.WriteLine(Generic<string>.Foo); // 20
}
}
As you can see, Generic<string>.Foo is a different field from Generic<object>.Foo - they hold separate values.
From the JetBrains wiki:
In the vast majority of cases, having a static field in a generic type
is a sign of an error. The reason for this is that a static field in a
generic type will not be shared among instances of different close
constructed types. This means that for a generic class C<T> which
has a static field X, the values of C<int>.X and C<string>.X
have completely different, independent values.
In the rare cases when you do need the 'specialized' static fields,
feel free to suppress the warning.
If you need to have a static field shared between instances with
different generic arguments, define a non-generic base class to
store your static members, then set your generic type to inherit from
this type.
This is not necessarily an error - it is warning you about a potential misunderstanding of C# generics.
The easiest way to remember what generics do is the following:
Generics are "blueprints" for creating classes, much like classes are "blueprints" for creating objects. (Well, this is a simplification though. You may use method generics as well.)
From this point of view MyClassRecipe<T> is not a class -- it is a recipe, a blueprint, of what your class would look like. Once you substitute T with something concrete, say int, string, etc., you get a class. It is perfectly legal to have a static member (field, property, method) declared in your newly created class (as in any other class) and no sign of any error here.
It would be somewhat suspicious, at first sight, if you declare static MyStaticProperty<T> Property { get; set; } within your class blueprint, but this is legal too. Your property would be parameterized, or templated, as well.
No wonder in VB statics are called shared. In this case however, you should be aware that such "shared" members are only shared among instances of the same exact class, and not among the distinct classes produced by substituting <T> with something else.
There are several good answers here already, that explain the warning and the reason for it. Several of these state something like having a static field in a generic type generally a mistake.
I thought I'd add an example of how this feature can be useful, i.e. a case where suppressing the R#-warning makes sense.
Imagine you have a set of entity-classes that you want to serialize, say to Xml. You can create a serializer for this using new XmlSerializerFactory().CreateSerializer(typeof(SomeClass)), but then you will have to create a separate serializer for each type. Using generics, you can replace that with the following, which you can place in a generic class that entities can derive from:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Since your probably don't want to generate a new serializer each time you need to serialize an instance of a particular type, you might add this:
public class SerializableEntity<T>
{
// ReSharper disable once StaticMemberInGenericType
private static XmlSerializer _typeSpecificSerializer;
private static XmlSerializer TypeSpecificSerializer
{
get
{
// Only create an instance the first time. In practice,
// that will mean once for each variation of T that is used,
// as each will cause a new class to be created.
if ((_typeSpecificSerializer == null))
{
_typeSpecificSerializer =
new XmlSerializerFactory().CreateSerializer(typeof(T));
}
return _typeSpecificSerializer;
}
}
public virtual string Serialize()
{
// .... prepare for serializing...
// Access _typeSpecificSerializer via the property,
// and call the Serialize method, which depends on
// the specific type T of "this":
TypeSpecificSerializer.Serialize(xmlWriter, this);
}
}
If this class was NOT generic, then each instance of the class would use the same _typeSpecificSerializer.
Since it IS generic however, a set of instances with the same type for T will share a single instance of _typeSpecificSerializer (which will have been created for that specific type), while instances with a different type for T will use different instances of _typeSpecificSerializer.
An example
Provided the two classes that extend SerializableEntity<T>:
// Note that T is MyFirstEntity
public class MyFirstEntity : SerializableEntity<MyFirstEntity>
{
public string SomeValue { get; set; }
}
// Note that T is OtherEntity
public class OtherEntity : SerializableEntity<OtherEntity >
{
public int OtherValue { get; set; }
}
... let's use them:
var firstInst = new MyFirstEntity{ SomeValue = "Foo" };
var secondInst = new MyFirstEntity{ SomeValue = "Bar" };
var thirdInst = new OtherEntity { OtherValue = 123 };
var fourthInst = new OtherEntity { OtherValue = 456 };
var xmlData1 = firstInst.Serialize();
var xmlData2 = secondInst.Serialize();
var xmlData3 = thirdInst.Serialize();
var xmlData4 = fourthInst.Serialize();
In this case, under the hood, firstInst and secondInst will be instances of the same class (namely SerializableEntity<MyFirstEntity>), and as such, they will share an instance of _typeSpecificSerializer.
thirdInst and fourthInst are instances of a different class (SerializableEntity<OtherEntity>), and so will share an instance of _typeSpecificSerializer that is different from the other two.
This means you get different serializer-instances for each of your entity types, while still keeping them static within the context of each actual type (i.e., shared among instances that are of a specific type).

Can we interrupt creating an object in constructor

Could you help me please.
I have one idea but don't know how can I implement it.
So the question is:
Can we interrupt creating an object in constructor
i.e.
//Code
SomeClass someClass = new SomeClass(someCriteria);
So if someCriteria doesn't answer on our requirements we shouldn't create an object and should return null, instead of new object.
Is it possible to implement it in C#?
Best way is a factory class but if your class is so small you can use this:
class SomeClass
{
private string _someCriteria;
private SomeClass(string someCriteria)
{
_someCriteria = someCriteria;
}
public static SomeClass CreateInstance(string someCriteria)
{
if (someCriteria.Length > 2)
{
return new SomeClass(someCriteria);
}
return null;
}
}
class Program
{
static void Main(string[] args)
{
// returns null
SomeClass someClass = SomeClass.CreateInstance("t");
// returns object
SomeClass someClass2 = SomeClass.CreateInstance("test");
}
}
You may want to use a factory class that creates instances of SomeClass returning null if the someCriteria is invalid.
It is quite usual that you check the constructor parameters if they are valid. If not, you usually throw an exception.
I also read a nice advice to provide static methods for validating constructor parameters. This enables the user of your class to check if whatever he is going to pass in the constructor will succeed or not. Those who are certain the parameters are ok (they made some sort of their validation) will go directly with the constructor.
Also consider what the user of your class will possibly do with null instead of the object (if some sort of factory class was used). Would this typically result in an NullPointerException on the next line? It's usually good idea to stop the wrong things as soon as possible, in this case throw the exception and finish. It is cleaner solution than returning null and if someone really wants to (this definetly won't be best practise) he can still catch this exception ...
If the parameters to your constructor are invalid, consider throwing ArgumentException or one of its descendant classes (e.g. ArgumentOutOfRangeException).
The new construct guarantees that an object will be returned (or an exception thrown). So as bleeeah recommended, a factory or similar concept will allow you to apply your logic.
That would be possible. Another way would be to put your checking in before you create the object. Like so
SomeClass someClass = null;
if (someCriteria == VALID)
{
someClass = new SomeClass(someCriteria);
}
Hope this helps.
No it is not possible directly.
You could throw an exception and add the required code to check for the exception and assign null to you variable.
A better solution would be to use a Factory that would return null if some condition fail.
var someClass = SomeClassFactory.Create(someCriteria);
if(someClass != null)
{
}

Object Initialization and "Named Constructor Idiom"

Ok. So I have a list of values, and I'd like to do something like the following:
MyObjectValues
.Select(currentItems=>new MyType()
{
Parameter1 = currentItems.Value1,
Parameter2 = currentItems.Value2
});
So here's the problem. I need the above example to work with named constructors, such as:
MyObjectValues
.Select(currentItems=>MyType.GetNewInstance()
{
Parameter1 = currentItems.Value1,
Parameter2 = currentItems.Value2
});
Is there any way I can do that? Basically, I have a static method I need to call to get the object instance back, and I'd like to initialize it as above.
EDIT: I don't have an easy way to modify the interface of MyType at present, so adding new function calls (while probably the 'best' approach) isn't very practical at the moment.
Unfortunately there's no direct support for this in C# 3.0. Object initializers are only supported for constructor calls. However, you might consider the Builder pattern. In my Protocol Buffers port, I support it like this:
MyType foo = new MyType.Builder {Parameter1 = 10, Parameter2 = 20}.Build();
So your example would become:
MyObjectValues.Select(currentItems => new MyType.Builder
{
Parameter1 = currentItems.Value1,
Parameter2 = currentItems.Value2
}.Build());
Of course, it means writing the nested Builder type, but it can work quite well. If you don't mind MyType being strictly speaking mutable, you can leave an immutable API but make an instance of Builder immediately create a new instance of MyType, then set properties as it goes (as it has access to private members), and then finally return the instance of MyType in the Build() method. (It should then "forget" the instance, so that further mutation is prohibited.)
I'm sure someone will think of a clever way to do it in pre 4.0 C#, but I just read Sam Ng's blog post on named parameters in C# 4.0. This should solve your problem. It would look like this:
MyObjectValues.Select(currentItems=>MyType.GetNewInstance(
Parameter1:currentItems.Value1,
Parameter2:currentItems.Value2));
EDIT
Forgot to mention, what makes this useful is that you can set defaults for the parameters, so you don't have to pass them all. The blog post is a good short summary.
Update: how about a factory:
MyObjectValues.Select(currentItems=>MyTypeFactory.GetNewInstance(currentItems.Value1,
currentItems.Value2));
public static class MyTypeFactory
{
public static MyType GetNewInstance(
typeofvalue1 value1,
typeofvalue2 value2)
{
return new MyType { Parameter1 = value1, Parameter2 = value2 };
}
}

Categories