I have this variable, it's an instance of a Interface of a class in business layer.
I need to send messages since data access layer, to business layer and finally to presentation layer. I my class "LogBinaryWriter" in data access I have this:
public class LogBinaryWriter : ILogBinaryWriter
{
private readonly IImageLogBuilder _imageLogBuilder;
public void WriteFrameCodes(string filePath, int logSelected)
{
var fileExists = FileExists(binaryFilePath);
if (fileExists == true)
{
_imageLogBuilder.displayMessage("The file " + binaryFileName + " exist. Dou you want overwrite it? (Y/N)");
}
}
}
I have a message: "the value _imageLogBuilder is never assigned and will always be null"
How can I fix this?
Instantiate an instance of IImageLogBuilder in your constructor for LogBinaryWriter and assign it to _imageLogBuilder. You would have to do it in the constructor since you have _imageLogBuilder marked as readonly.
For example, assuming you have a class called MyImageLogBuilder that implements IImageLogBuilder:
public LogBinaryWriter()
{
_imageLogBuilder = new MyImageLogBuilder();
}
You could also overload the constructor so you can pass in the IImageLogBuilder you want to use (lookup constructor injection for more info on this pattern):
public LogBinaryWriter(IImageLogBuilder imageLogBuilder)
{
_imageLogBuilder = imageLogBuilder;
}
Remember, you will need a class that implements the IImageLogBuilder interface to be able to create a new instance and assign it to the _imageLogBuilder variable. For example:
public interface IImageLogBuilder
{
void Log(string message);
}
//The class below IMPLEMENTS the IImageLogBuilder interface
public class MyImageLogBuilder : IImageLogBuilder
{
//Implement IImageLogBuilder methods here
public void Log(string message)
{
//Log message
}
}
If you had something like the classes defined above then you could the following in the LogBinaryWriter constructor and you would no longer get the null reference error.
public LogBinaryWriter()
{
_imageLogBuilder = new MyImageLogBuilder();
}
You need to assign an instance of a class that implements IImageLogBuilder interface to _imageLogBuilder field.
Right now your field will always have a value of null.
For example:
private readonly IImageLogBuilder _imageLogBuilder = new ImageLogBuilder();
perhaps initialize _imageLogBuilder in constructor ?
public class LogBinaryWriter : ILogBinaryWriter
{
private readonly IImageLogBuilder _imageLogBuilder;
public LogBinaryWriter(IImageLogBuilder imageLogBuilder)
{
_imageLogBuilder = imageLogBuilder;
}
....
}
You never set the value of the _imageLogBuilder variable. And since you marked it as readonly, the only place it can be set is in a field initializer, or in a constructor.
Did you mean to do something like this, perhaps?
private readonly IImageLogBuilder _imageLogBuilder = // get the value from somewhere else, or make a new one
Related
I was trying to implement a singleton inheritance for my log system, so I would be able to separate the system events from user behavior. I found this nice post in Java. Despite the Generics difference I could implemente this attached first version (non thread safe for a while).
public abstract class Log
{
private static volatile Dictionary<Type, Log> instances = new Dictionary<Type, Log>();
public static Log GetInstance(Type type) {
Log instance = null;
if (!Log.instances.ContainsKey(type))
{
ConstructorInfo ctor = type.GetConstructor(BindingFlags.Default,
null,
new Type[0],
new ParameterModifier[0]);
instance = ctor.Invoke(new object[0]) as Log;
instances.Add(type, instance);
}
else
{
instance = Log.instances[type];
}
return instance;
}
private Log() { }
public class UserLog : Log
{
private UserLog() : base() { }
}
public class SystemLog : Log
{
private SystemLog() : base() { }
}
}
The highlight line above shows the attempt to create a new instance. But is doesn't work and returns a null instance of ConstructorInfo.
1) Any ideia about how to use the GetConstructor method? I know it has 3 overloaded versions, but the first one is only for public constructors. If I change the visibility of the constructor to public I can use other overloaded version (this one), but this specific version I can't even with public constructors.
2) In C#, is it possible to call a private constructor from other class like I'm trying to do? I have implemented it in Java, but in C# it might be different.
Since your binding flags don't specify Private, you won't get your private constructors. If there were public, you'd need to specify Public.
That said, I don't understand your desire to implement this in this way. It seems like a lot of extra work for no good reason.
I would do it like this:
public abstract class Log
{
public class UserLog : Log
{
private static readonly Lazy<UserLog> _instance =
new Lazy<UserLog>(() => new UserLog());
public static UserLog Instance { get { return _instance.Value; } }
}
public class SystemLog : Log
{
private static readonly Lazy<SystemLog > _instance =
new Lazy<SystemLog >(() => new SystemLog ());
public static SystemLog Instance { get { return _instance.Value; } }
}
}
I.e. just follow the normal singleton idiom for each of the actual singleton classes.
If you specify that the generic type will have to inherit from Log, and that it will have the new(), you can get away with using the parameterless constructor. You also would have to change your constructor to protected so that the child class can call it:
public abstract class Log
{
private static volatile Dictionary<Type, Log> instances = new Dictionary<Type, Log>();
public static TLogType GetInstance<TLogType>() where TLogType : Log, new()
{
TLogType instance = null;
var type = typeof(TLogType);
if (!Log.instances.ContainsKey(type))
{
instance = new TLogType();
instances.Add(type, instance);
}
else
{
instance = (TLogType)Log.instances[type];
}
return instance;
}
protected Log() { }
}
I don't think you can call the private constructors outside the class (they are private, after all), but through reflection there may be something that can be done (I'm no reflection expert). Using protected instead of private may get you the results you want.
I am reading Beginning Visual C# 2012.
Consider:
using System;
using System.Collections.Generic;
using System.Text;
namespace Ch10Ex01
{
class MyClass
{
public readonly string Name;
private int intVal;
public int Val
{
get { return intVal; }
set
{
if (0 <= value && value <= 10)
intVal = value;
else
throw (new ArgumentOutOfRangeException("Val", value,
"Val must be assigned a value between 0 and 10."));
}
}
public override string ToString()
{
return "Name: " + Name + "\nVal: " + Val;
}
private MyClass() : this("Default Name")
{
}
public MyClass(string newName)
{
Name = newName;
intVal = 0;
}
}
}
Explanation in the book: Note that I've used this ("Default Name") to ensure that Name gets a value if this constructor ever gets called, which is possible if this class is used to derive a new class. This is necessary as not assigning a value to the Name field could be a source of errors later.
What's puzzling me: How can it be used in a derived class as it's "private"? What does this ("Default Name") mean? How does the object get the "Default Name" as its name?
What's puzzling me: How can it be used in a derived class as it's "private"? What does this("Default Name") mean? **How does the object get the "Default Name" as its name?
You are right to be puzzled!
That code sample does not call the default constructor at all - and because it is private, nothing else can call it without using reflection (not even a derived class; it would have to be at least protected for a derived class to call it - or the derived class would have to be nested within the base class).
In the sample code, the object does not get "Default Name" as its value.
So it's a typo or an error in the book.
The correct solution to what the book is describing is to:
Omit the default constructor altogether.
Initialise Name at field scope. This ensures that it is impossible to fail to initialise it, no matter what other constructors are written in this or any derived class.
Like so:
class MyClass
{
public readonly string Name = "Default Name";
private int intVal;
public int Val
{
get
{
return intVal;
}
set
{
if (0 <= value && value <= 10)
intVal = value;
else
throw (new ArgumentOutOfRangeException("Val", value,
"Val must be assigned a value between 0 and 10."));
}
}
public override string ToString()
{
return "Name: " + Name + "\nVal: " + Val;
}
public MyClass(string newName)
{
Name = newName;
intVal = 0;
}
}
Note that it can often be useful to declare a private default constructor which is called by other constructors - but the declaring class has to actually use it.
Also note that if you declare a non-default constructor in a base class and do not declare a default constructor at all, any derived class must call one of the existing base class constructors.
For example given the class definition above, then both the following class declarations will cause a compile error MyClass' does not contain a constructor that takes 0 arguments:
class MyDerivedClass1: MyClass
{
public MyDerivedClass1() // Compile error
{
}
}
class MyDerivedClass2: MyClass
{
// No constructor declared at all. Also a compile error.
}
To fix the error, MyDerivedClass has to call an existing constructor:
class MyDerivedClass: MyClass
{
public MyDerivedClass(): base("My new name")
{
}
}
So what use is a private constructor
A fairly typical use is to put common initialisation code into a default constructor. Sometimes, however, you don't want the caller to be able to default-construct the type - in which case you can make the default constructor private.
That way, you can still use the default constructor for common initialisation but you prevent code outside the class from doing it, for example:
class Test
{
public readonly int IntValue;
public readonly string StringValue;
private Test()
{
// Do common initialisation.
}
public Test(int intValue): this()
{
IntValue = intValue;
}
public Test(string stringValue): this()
{
StringValue = stringValue;
}
}
Often you could just use a private init() method to do the common initialisation, but if you are initialising a readonly field you must use a constructor to do so. In that case, a private constructor must be used instead of an init() method.
Another use of a private default constructor is to prevent any instantiation of the type at all (you just declare a private default constructor and no other constructors at all).
In .Net 1.x that was the only way to do so - but subsequent versions of .Net introduced static classes which for most cases removed the need to use a private constructor for that type.
You might also declare a private constructor to force the use of a static factory method to instantiate the type.
Just for completeness, here's a contrived example that demonstrates how a private constructor can be called from a nested derived class:
class OuterClass
{
public readonly string Value;
private OuterClass(): this("Default Value")
{
}
public OuterClass(string value)
{
Value = value;
}
public OuterClass GetInnerClass()
{
return new InnerClass();
}
private class InnerClass: OuterClass
{
}
}
With that class definition, the following code will print "Default Value":
OuterClass test = new OuterClass("Test");
Console.WriteLine(test.GetInnerClass().Value);
Personally I've never had to write a nested class that derives from its containing class, but it's possible if you need to do it for some reason.
Because this class has a private constructor, the ONLY way that the constructor can be called is within this particular class. Not even a derived class can call it (if it was protected then it could). As your code example shows, this serves no purpose.
The reason why it's a default constructor calling another is just a way of having a hard-coded default value without the user knowing/caring what it is. This is similar to default parameters for functions in .NET 4.0.
To me, it would make much more sense to make both constructors public, because I don't see any code that uses the default constructor (if you have shown us all the code).
There are some legitimate reasons to use private constructors, specifically with static functions or sub-classes. Take the following for example:
public class OuterClass
{
private OuterClass() { }
public static OuterClass GetOuter() { return new OuterClass(); }
}
In this way, you can only make a new instance of the class from the static method.
A private constructor means a user can not directly instantiate a class. Instead, you can create objects using something like the named constructor Idiom, where you have static class functions that can create and return instances of a class. You can use the private constructor to control the instantion of the Object usually used in the singleton pattern.
You have to read the singleton pattern to understand the purpose of the private constructor.
I have the following code implementation of my generic singleton provider:
public sealed class Singleton<T> where T : class, new()
{
Singleton()
{
}
public static T Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator()
{
}
internal static readonly T instance = new T();
}
}
This sample was taken from 2 articles and I merged the code to get me what I wanted:
http://www.yoda.arachsys.com/csharp/singleton.html and
http://www.codeproject.com/Articles/11111/Generic-Singleton-Provider.
This is how I tried to use the code above:
public class MyClass
{
public static IMyInterface Initialize()
{
if (Singleton<IMyInterface>.Instance == null // Error 1
{
Singleton<IMyInterface>.Instance = CreateEngineInstance(); // Error 2
Singleton<IMyInterface>.Instance.Initialize();
}
return Singleton<IMyInterface>.Instance;
}
}
And the interface:
public interface IMyInterface
{
}
The error at Error 1 is:
'MyProject.IMyInterace' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'MyProject.Singleton<T>'
The error at Error 2 is:
Property or indexer 'MyProject.Singleton<MyProject.IMyInterface>.Instance' cannot be assigned to -- it is read only
How can I fix this so that it is in line with the 2 articles mentioned above? Any other ideas or suggestions are appreciated.
Does my implementation break the Singleton pattern?
Basically, you've given a class constraint on your singleton class, along with the new() constraint.
When writing
Singleton<IMyInterface>
you're using an interface type as T, which violates the type constraint you defined.
For error 2,
Singleton<IMyInterface>.Instance = CreateEngineInstance();
you're trying to assign a value to a read-only property. So you need to define a setter on your Instance property for that line to work.
Update
Something along these lines should do it for you :
public sealed class Singleton
{
private static Hashtable bindings = new Hashtable();
private static Hashtable instances = new Hashtable();
private static void checkType(Type requested, Type bound)
{
if (requested.IsValueType)
throw new Exception("Cannot bind a value type to a reference type");
// also check type inheritance and other things...
}
private static void checkBinding(Type requested)
{
if (!(bindings.ContainsKey(requested)))
throw new Exception(String.Format("Type {0} was not bound !", requested.FullName));
}
public static void Bind<T, U>() where U : class, new()
{
checkType(typeof(T), typeof(U));
bindings[typeof(T)] = typeof(U);
}
public static T GetInstance<T>()
{
Type requested = typeof(T);
Type bound = (Type) bindings[requested];
checkBinding(requested);
if (!instances.ContainsKey(requested)) {
// We know that type "bound" was set with a new() class constraint
instances[requested] = (T) Activator.CreateInstance(bound);
}
return (T) instances[requested];
}
}
You could then write :
Singleton.Bind<IMyInterface, MyClass>();
IMyInterface instance = Singleton.GetInstance<IMyInterface>();
If you want to go further, you could also specify the lifecycle of the objects created by this provider, so that you could use singletons, or have the provider return a new object for each call, and so on.
You should also take a look at the Dependency Injection pattern, which seems close to what you want achieve, and also look at existing DI frameworks (NInject, Nhibernate) that already do this and much more.
Sure, you have an issue there. You generic is suppose to take class, not interface.
internal static readonly T instance = new T();
Your code suppose to create an instance of that class, you could not instantiate interface type.
So, if you need some type to act as singletone, you should write:
Singleton<MyInterface>.Instance
where
public class MyInterface : IMyInterface { }
Then you don't need to have any 'if' in you code, since it Singleton responsibility to instantite an object and keep it as only one instance.
Not related to question: currently Singletone's are considered by many developers as 'code-smell', so in general you have to avoid them. Try to think you application without Singletone at all.
I have an interface based class that I want to have a few static classes as properties. However, I can't seem to find a way to use a static class as an instance property on a class based on an interface.
public interface IHttpHelp
{
ItemsManager {get;set;}
}
public static class ItemsManager
{
//static methods
}
public class HttpHelper
{
public ItemsManager { get { return ItemsManager;}
}
The above code won't work because of the "ItemsManager is used like a variable but it's a type error." Is there anyway to use a class this way?
For some insight into what I'm doing - I have a few static helper classes that access the httpruntime and current context. I currently use them directly, but wanted to move into a container class that will be used IoC. I could make them instance classes and forget about it, but I'm wondering f there's a way to this.
You can't use a static class like that, because by definition you can't create an instance of it, so you can't return it from a property. Make it a singleton instead:
public class ItemsManager
{
#region Singleton implementation
// Make constructor private to avoid instantiation from the outside
private ItemsManager()
{
}
// Create unique instance
private static readonly ItemsManager _instance = new ItemsManager();
// Expose unique instance
public static ItemsManager Instance
{
get { return _instance; }
}
#endregion
// instance methods
// ...
}
public class HttpHelper
{
public ItemsManager ItemsManager { get { return ItemsManager.Instance; } }
}
This is not supported by the language directly. You can either write a proxy class manually or use a library like the Duck Typing Project to emit a proxy class at runtime.
Both will have the same result: you will have a class that implements the interface, and proxies all calls to the static methods of the static class. Whether you want to write this yourself or use the duck typing library is up to you.
EDIT: Thomas' answer of using a singleton would be the way to go, if you have that option.
Static classes can't implement interfaces--it really wouldn't make much sense. An interface provides a standard API that all instances will support and you can swap instances and polymorphically access the methods through the standard interface. With a static class, all references to it are through the class anyways.
Typically in this situation you want a factory to support DI of an instance class that implements your helper.
public interface IHttpHelper
{ }
public class RealHttpHelper
{ ... }
public class FakeHttpHelper
{ ... }
public static class HttpHelper
{
public static IHttpHelper Instance
{
get
{
return whatever ? new RealHttpHelper() : new FakeHttpHelper();
}
}
}
...
HttpHelper.Instance.Context...
...
The Base Class:
public class DatabaseBase
{
private readonly string connectionString;
private bool useCounters;
public DatabaseBase(string connectionString)
{
this.connectionString = connectionString;
}
public DatabaseBase(...)
{
connectionString = ...;
}
public DatabaseBase(..)
{
connectionString = string.Format(...);
}
public string ConnectionString
{
get { return this.connectionString; }
}
...
The derived class:
public class ProjectDB : DatabaseBase
{
private bool useServiceConnection;
private static string ConnectionString
{
get
{
string connectionString = useServiceConnection == true ? ConfigurationManager.AppSettings["SomeConnection1"] : ConfigurationManager.AppSettings["SomeConnection2"];
return connectionString;
}
}
public ProjectDB() : this(false)
{
}
private bool isServiceCall;
public ProjectDB(bool useServiceConnection)
: base(ConnectionString)
{
this.useServiceConnection = useServiceConnection;
}
private SqlConnection CreateConnection()
{
return new SqlConnection(ConnectionString);
}
I'm getting the error "Cannot access non-static field useServiceConnection in static context" for this line:
string connectionString = useServiceConnection == true ? ConfigurationManager.AppSettings["SomeConnection1"] : ConfigurationManager.AppSettings["SomeConnection2"];
However if I make useServiceConnection a static var to satisfy the quirement, then I get that same error here in the constructor:
public ProjectDB(bool useServiceConnection)
: base(ConnectionString)
{
this.useServiceConnection = useServiceConnection;
}
Now if I make useServiceConnection and ConnectionSting property non-static, then I get that error for the constructor here:
public LitleDB(bool useWebServiceConnection)
: base(ConnectionString)
{
this.useWebServiceConnection = useWebServiceConnection;
}
I think the first 2 I understand.
But now with the example updated below, why would the constructor in this case give me an error still? Those are no longer static so where's the static context being expected from? So here's what I have now:
public class ProjectDB : DatabaseBase
{
private bool useServiceConnection; <-- NO LONGER STATIC
private new string ConnectionString <-- NO LONGER STATIC
{
get
{
string connectionString = useServiceConnection == true ? ConfigurationManager.AppSettings["SomeConnection1"] : ConfigurationManager.AppSettings["SomeConnection2"];
return connectionString;
}
}
public ProjectDB() : this(false)
{
}
private bool isServiceCall;
public ProjectDB(bool useServiceConnection)
: base(ConnectionString) <--- IT'S COMPLAINING HERE NOW, SO WHERE IS IT TRYING TO ACCESS STATICALLY? I DON'T GET WHY
{
this.useServiceConnection = useServiceConnection;
}
I have other static properties in this class, does that have anything to do with it? I'm not using them though.
The variable useServiceConnection is not static so it only exists within the context of an instance of the class. Since the property ConnectionString is static, it does not exist in the context of an instance, and so it cannot "see" instance members. You will need to either make ConnectionString not being static, or make useServiceConnection static.
A static member belongs to a type rather than a specific instance of a type. It doesn't matter whether you have no instances of a class or you create a million instances when it comes to static members. Only one will exist. This is not the case for instance variables. Basically, each instance you create has its own specific instance variables. This is why you can't access instance members in static contexts without an object instance. It's not clear the instance member you want to access belongs to which object. You can, however, reference instance members in static contexts by specifying an object reference explicitly:
obj.instanceMember // valid in static context as `obj` specifies the object
Static members are a property of the class itself. You don't even have to have any instances of Database created anywhere to access Database.ConnectionString when ConnectionString is a static property.
So, inside your property declaration, when you try to access "useServiceConnection", it doesn't know what you're talking about. useServiceConnection is an instance variable - it only exists for a given instance of the Database class. What if there were no database classes instantiated? What if there were 5? It doesn't make sense to access instance members of a class from a static scope.
I would make your ConnectionString property non-static, as it doesn't really seem like something that should be static anyway.
Make the ConnectionString and useWebServiceConnection in the LitleDb class instance members also.
However, I don't think that your constructors will work properly once they compile. You are calling the base constructor with the value from ConnectionString as parameter, but at that time you haven't set the useServiceConnection variable, so it will always be false and the ConnectionString property will always return the second connection string.