In my senario, I have a global setting object, say GlobalSettings, it has a static property "Current" (singleton), and there should be only one GlobalSettings instance.
But...In my data model, there's an entity "LocalizedContent":
public class LocalizedContent {
public string Title { get; set; }
public string Content { get; set; }
public string CultureName { get; set; }
}
In the constructor, I want to initialize the instance by setting CultureName to default culture of the system, and I can get the default culture name from GlobalSettings.Current.DefaultCultureName.
However, I don't want to use the singleton property "GlobalSettings.Current" in LocalizedContent class, since it will result in strong-coupling. So my question is, where is the right place to set this default culture name?
Thanks in advance!
Why not add a constructor to LocalizedContent that takes the DefaultCultureName as a parameter?
LocalizedContent can then be re-used without a dependency on GlobalSettings.
I think the trick here is to add a constructor to the LocalizedContent class which takes in the values it needs to consume.
public LocalizedContent {
public LocalizedContent(string cultureName) {
this.CultureName = cultureName;
}
}
For convenience sake you could also add a helper method which creates the LocalizedContent method using the GlobalSettings values.
public static LocalizedContent CreateLocalizedContent() {
return new LocalizedContent(GlobalSettings.Current.DefaultCultureName);
}
Hm, you may wish to check this out.
In short, what you would like to do is, inject a "culture" source into your localized content object. Consider the following example,
// your public global settings singleton, no big surprises here
// except possibly thread safe locking [shrug] if you are singlethreaded
// you can simplify this model further
public class GlobalSettings
{
// singleton synchronization and instance reference
private static readonly object _instanceSyncRoot = new object ();
private static readonly GlobalSettings _instance = null;
// instance-based synchronization and values
private readonly object _syncRoot = new object ();
private string _cultureName = string.Empty;
// gets public static instance
public static GlobalSettings Current
{
get
{
lock (_instanceSyncRoot)
{
if (_instance == null)
{
_instance = new GlobalSettings ();
}
}
return _instance;
}
}
// gets public culture name
public string CultureName
{
get { lock (_syncRoot) { return _cultureName; } }
set { lock (_syncRoot) { _cultureName = value; } }
}
// private constructor to re-inforce singleton semantics
private GlobalSettings () { }
}
So, a number of things. Typically singletons like this are frowned upon - they are very convenient! but as you point out, lead to tight-coupling between functional components and configuration.
If you would like to move away from this tight coupling, while preserving what exists, you have a few options, easiest being
// define a general-purpose settings interface, i do not much
// care for refactor tools, but you may use re-sharper or built in
// refactor components to "extract" those properties from global
// settings that you need. here we pull out culture name only,
public interface ISettings
{
// gets culture name from underlying settings implementation
string CultureName { get; }
}
public class LocalizedContent
{
public string CultureName { get; set; }
public LocalizedContent (ISettings settings)
{
CultureName = settings.CultureName;
}
}
If you are able to modify GlobalSettings singleton,
// public singleton is now an implementation of a "loosely coupled
// component" called ISettings
public class GlobalSettings : ISettings { ... }
// elsewhere in code
public LocalizedContent GetLocalizedContent ()
{
LocalizedContent content = new LocalizedContent (GlobalSettings.Instance);
return content;
}
If you are not able to modify GlobalSettings singleton,
// wrapper class for global settings singleton
public class Settings : ISettings
{
public string CultureName
{
get { return GlobalSettings.Instance.CultureName; }
}
}
// elsewhere in code
public LocalizedContent GetLocalizedContent ()
{
LocalizedContent content = new LocalizedContent (new Settings ());
return content;
}
Now, LocalizedContent is no longer tightly-coupled to GlobalSettings singleton. In fact, any implementation of ISettings will satisfy its constructor dependency.
If your dependencies are as simple as a string or two, this may be overkill. However, if you have other complex components dependent on this global singleton, this approach may be for you :)
Related
Is there an easy way to make an instance immutable?
Let's do an example, I have a class holding a lots of data fields (only data, no behavior):
class MyObject
{
// lots of fields painful to initialize all at once
// so we make fields mutable :
public String Title { get; set; }
public String Author { get; set; }
// ...
}
Example of creation:
MyObject CreationExample(String someParameters)
{
var obj = new MyObject
{
Title = "foo"
// lots of fields initialization
};
// even more fields initialization
obj.Author = "bar";
return obj;
}
But now that I have fully created my object, I don't want the object to be mutable anymore (because the data consumer will never need to change the state), so I would like something like that List.AsReadOnly:
var immutableObj = obj.AsReadOnly();
But if I want this behavior, I need to make another class that have exactly the same fields but without setter.
So is there any automatic way to generate this immutable class ? Or another way to allow mutability during creation but immutable once initialized ?
I know that fields can be marked as "readonly", but the object will be initialized outside of the class, and passing all fields as constructor parameters seems like a bad idea (too much parameters).
No, there is no easy way to make any type immutable, especially not if you want "deep" immutability (i.e. where no mutable object can be reached through the immutable object). You will have to explicitly design your types to be immutable. The usual mechanisms to make types immutable are these:
Declare (property-backing) fields readonly. (Or, starting with C# 6 / Visual Studio 2015, use read-only auto-implemented properties.)
Don't expose property setters, only getters.
In order to initialize (property-backing) fields, you must initialize them in the constructor. Therefore, pass the (property) values to the constructor.
Don't expose mutable objects, such as collections based on mutable-by-default types (like T[], List<T>, Dictionary<TKey,TValue>, etc.).
If you need to expose collections, either return them in a wrapper that prevents modification (e.g. .AsReadOnly()), or at the very least return a fresh copy of the internal collection.
Use the Builder pattern. The following example is too trivial to do the pattern justice, because it's usually recommended in cases where non-trivial object graphs need to be created; nevertheless, the basic idea is something like this:
class FooBuilder // mutable version used to prepare immutable objects
{
public int X { get; set; }
public List<string> Ys { get; set; }
public Foo Build()
{
return new Foo(x, ys);
}
}
class Foo // immutable version
{
public Foo(int x, List<string> ys)
{
this.x = x;
this.ys = new List<string>(ys); // create a copy, don't use the original
} // since that is beyond our control
private readonly int x;
private readonly List<string> ys;
…
}
Hmm I will enumerate my first thought on this...
1. Use internal setters if your only worry is manipulation outside of your assembly. internal will make your properties available to classes in the same assembly only. For example:
public class X
{
// ...
public int Field { get; internal set; }
// ...
}
2. I don't agree that it's necessarily a bad idea to have lots of parameters in your constructor.
3. You could generate another type at runtime that is a read-only version of your type. I can elaborate on this, but personally I think this is overkill.
Best, Iulian
As another solution you can use Dynamic Proxy. Alike approach was used for Entity Framework http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx. Here is example how you can do it using Castle.DynamicProxy framework. This code is based on original example from Castle Dynamic proxy (http://kozmic.net/2008/12/16/castle-dynamicproxy-tutorial-part-i-introduction/)
namespace ConsoleApplication8
{
using System;
using Castle.DynamicProxy;
internal interface IFreezable
{
bool IsFrozen { get; }
void Freeze();
}
public class Pet : IFreezable
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
public virtual bool Deceased { get; set; }
bool _isForzen;
public bool IsFrozen => this._isForzen;
public void Freeze()
{
this._isForzen = true;
}
public override string ToString()
{
return string.Format("Name: {0}, Age: {1}, Deceased: {2}", Name, Age, Deceased);
}
}
[Serializable]
public class FreezableObjectInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
IFreezable obj = (IFreezable)invocation.InvocationTarget;
if (obj.IsFrozen && invocation.Method.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
{
throw new NotSupportedException("Target is frozen");
}
invocation.Proceed();
}
}
public static class FreezableObjectFactory
{
private static readonly ProxyGenerator _generator = new ProxyGenerator(new PersistentProxyBuilder());
public static TFreezable CreateInstance<TFreezable>() where TFreezable : class, new()
{
var freezableInterceptor = new FreezableObjectInterceptor();
var proxy = _generator.CreateClassProxy<TFreezable>(freezableInterceptor);
return proxy;
}
}
class Program
{
static void Main(string[] args)
{
var rex = FreezableObjectFactory.CreateInstance<Pet>();
rex.Name = "Rex";
Console.WriteLine(rex.ToString());
Console.WriteLine("Add 50 years");
rex.Age += 50;
Console.WriteLine("Age: {0}", rex.Age);
rex.Deceased = true;
Console.WriteLine("Deceased: {0}", rex.Deceased);
rex.Freeze();
try
{
rex.Age++;
}
catch (Exception ex)
{
Console.WriteLine("Oups. Can't change that anymore");
}
Console.WriteLine("--- press enter to close");
Console.ReadLine();
}
}
}
I would suggest having an abstract base type ReadableMyObject along with derived types MutableMyObject and ImmutableMyObject. Have constructors for all the types accept a ReadableMyObject, and have all the property setters for ReadableMyObject call an abstract ThrowIfNotMutable method before updating their backing field. Additionally, have ReadableMyObject support a public abstract AsImmutable() method.
Although this approach will require writing some boilerplate for each property of your object, that will be the extent of the required code duplication. The constructors for MutableMyObject and ImmutableMyObject will simply pass the received object to the base-class constructor. Class MutableMyObject should implement ThrowIfNotMutable to do nothing, and AsImmutable() to return new ImmutableMyObject(this);. Class ImmutableByObject should implement ThrowIfNotMutable to throw an exception, and AsImmutable() to return this;.
Code which receives a ReadableMyObject and wants to persist its contents should call its AsImmutable() method and store the resulting ImmutableMyObject. Code which receives a ReadableMyObject and wants a slightly-modified version should call new MutableMyObject(theObject) and then modify that as required.
You kind of hinted at a way in your question, but I'm not sure if this is not an option for you:
class MyObject
{
// lots of fields painful to initialize all at once
// so we make fields mutable :
public String Title { get; protected set; }
public String Author { get; protected set; }
// ...
public MyObject(string title, string author)
{
this.Title = title;
this.Author = author;
}
}
Due to the constructor being the only way of manipulating your Author and Title, the class is in effect immutable after construction.
EDIT:
as stakx mentioned, I too am a big fan of using builders - especially because it makes unit testing easier. For the above class you could have a builder such as:
public class MyObjectBuilder
{
private string _author = "Default Author";
private string _title = "Default title";
public MyObjectBuilder WithAuthor(string author)
{
this._author = author;
return this;
}
public MyObjectBuilder WithTitle(string title)
{
this._title = title;
return this;
}
public MyObject Build()
{
return new MyObject(_title, _author);
}
}
This way you can construct your objects with default values, or override them as you please, but MyObject's properties can't be changed after construction.
// Returns a MyObject with "Default Author", "Default Title"
MyObject obj1 = new MyObjectBuilder.Build();
// Returns a MyObject with "George R. R. Martin", "Default Title"
MyObject obj2 = new MyObjectBuilder
.WithAuthor("George R. R. Martin")
.Build();
If you ever need to add new properties to your class, it's much easier to go back to your unit tests that consume from a builder rather than from a hardcoded object instantiation (i don't know what to call it, so pardon my terms).
Well, if you have too many parameters and you dont want to do constructors with parameters....here is an option
class MyObject
{
private string _title;
private string _author;
public MyObject()
{
}
public String Title
{
get
{
return _title;
}
set
{
if (String.IsNullOrWhiteSpace(_title))
{
_title = value;
}
}
}
public String Author
{
get
{
return _author;
}
set
{
if (String.IsNullOrWhiteSpace(_author))
{
_author = value;
}
}
}
// ...
}
Here's another option. Declare a base class with protected members and a derived class that redefines the members such that they are public.
public abstract class MyClass
{
public string Title { get; protected set; }
public string Author { get; protected set; }
public class Mutable : MyClass
{
public new string Title { get { return base.Title; } set { base.Title = value; } }
public new string Author { get { return base.Author; } set { base.Author = value; } }
}
}
Creating code will use the derived class.
MyClass immutableInstance = new MyClass.Mutable { Title = "Foo", "Author" = "Your Mom" };
But for all cases where immutability is expected, use the base class:
void DoSomething(MyClass immutableInstance) { ... }
I have implemented an interface IService that inherits functionality from a series of other interfaces and serves as a common ground for many different services.
Each of these services is being described by an interface, for example:
public interface IServiceOne : IService
{
//...
}
public class ServiceOne : IServiceOne
{
//...
}
Everything up to that point works as expected:
IServiceOne serviceOne = new ServiceOne();
IServiceTwo serviceTwo = new ServiceTwo();
What I have to do now is to add a big list of constants (public variables) to each of these services which will however be different as per service type (for example, IServiceOne will have different constants than IServiceTwo, there will be constants in IServiceOne that will not exist in IServiceTwo, etc).
What I'm trying to achieve is something like that:
IServiceOne serviceOne = new ServiceOne();
var someConstantValue = serviceOne.Const.SomeConstant;
Just because the variables will differ as of service type I decided to implement an extra interface for each of them:
public interface IServiceOneConstants
{
//...
}
and then broaden my IService definition:
public interface IServiceOne : IService, IServiceOneConstants
{
//...
}
public class ServiceOne : IServiceOne
{
//...
}
The problem I have now is that I don't know how to implement the concrete class for IServiceOneConstants. Obviously by the time one of its variables (we called them constants here) will be called it has to be instantiated, so initially I though of a static class but then you cannot expose a static class's functionality through an interface. I then tried to do it with a singleton and expose its instance via a public non-static wrapper:
public class Singleton : IServiceOneConstants
{
private static Singleton _instance;
private Singleton()
{
SomeConstant = "Some value";
}
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
public String SomeConstant { get; set; }
public Singleton Const
{
get
{
return Instance;
}
}
}
I then adjusted the IServiceOneConstants like that:
public interface IServiceOneConstants
{
Singleton Const { get; }
}
but when I call this:
IServiceOne serviceOne = new ServiceOne();
var someConstantValue = serviceOne.Const.SomeConstant;
I get a null reference exception, as .Const is null.
What am I missing here?
You really helped yourself to get confused as possible, by naming different stuff same name ;)
So, first...
what you're trying to do is to access singleton instance through instance property:
public Singleton Const
{
get
{
return Instance;
}
}
then you are using it like:
serviceOne.Const
but that variable was never assigned. In order to assign it, you should make an instance of Singleton class, assign it to serviceOne.Const property and then you might use it.
What you need is probably something like this:
public class ServiceOne : IServiceOne
{
public Singleton Const
{
get
{
return Singleton.Instance;
}
}
}
You need to check to see if the singleton has been instantiated in ServiceOne.Const.SomeConstants` getter. If it's not, you need to instantiate it. Then return the value of the constant.
I want to implement a class whose instance is global but whose property is to be initialized only once during the run time.
Also the initialization is to be done as an assignment from a result of function during execution.
Basically I want to do something like this
public class Configuration
{
public string param1 { get ; set; }
public int param2 { get; set; }
}
public static class AppConfig
{
public static readonly configuration;
}
public class Initialize
{
public void InitConfig()
{
AppConfig.configuration = GetParamsFromDB();
}
}
But I am unable to figure out how to implement it. Please ignore the above incorrect representation. It is just to present what is required.
EDIT
Also there is a need of seperate class Initialize because classes Configuration and AppConfig are in dll BO. GetParamsFromDB() is in DAL. DAL references BO hence
BO cannot refere DAL hence GetParamsFromDB() cannot be used within AppConfig class
All you need to do is initialize it inline:
public static class AppConfig
{
public static readonly configuration = GetParamsFromDB();
}
The C# runtime will automatically ensure that the parameter isn't initialized until the class is accessed for the first time, giving you your desired behvaior.
Note that your configuration type is mutable, which if you want to ensure these values aren't changed, is a bad thing. You should refactor your configuration class to accept the two values in its constructor and not provide public setters for the properties.
It looks like you want a singleton.
See: Implementing the Singleton Pattern in C#
public static class AppConfig
{
private static readonly Lazy<Configuration> _configuration = new Lazy<Configuration>(() => new Configuration());
public static Configuration Instance { get { return _configuration.Value; } }
}
However, you should consider changing your design as singletons are often overused.
Consider something that can be used with dependency injection and inversion of control.
Dependency injection is a pattern that increases code reuse and minimize dependencies through interfaces.
Inversion of control is a pattern that binds objects together at runtime typically using an assembler object.
Example:
public interface IAppConfig
{
Configuration Configuration { get; }
}
public sealed class AppConfig : IAppConfig
{
private readonly Configuration _configuration;
public AppConfiguration()
{
_configuration = new Configuration { };
}
public Configuration Configuration { get { return _configuration; } }
}
This can be used together with an IoC Container to provide configuration to all the objects that need it.
What you are trying to do is kind of Singleton Pattern, It can be implemented as follows,
public sealed class Configuration
{
private static volatile Configuration instance;
private static object syncRoot = new Object();
private Configuration() {}
public static Configuration Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Configuration();
}
}
return instance;
}
}
}
I have on my hands a Windows forms application where there is a clear separation of GUI and business logic. The solution is big (40 projects, thousands of classes, about 2000 database tables). My task is to find a solution on how to reuse business logic to build a web application as a front end.
The main issue is, I think, our static Session class which is used by every other class in the solution:
public static class Session
{
public static string CurrentUser { get; set; }
public static string CurrentDatabase { get; set; }
public static string CurrentCompanyProfile { get; set; }
public static string CurrentLanguage { get; set; }
}
This class will not work in ASP.NET where it will be shared by all users and I cannot replace it since it is used a lot.
I was thinking that I need to remove all information from this class and keep just the interface. By calling the get method of an property code would somehow redirect this call to HttpContext.Current.Session where I would store a class which would contain all this info.
I'm not sure how to do this properly considering that Session resides in an assembly which will not have a reference to System.Web and considering that I must not disrupt our WinForms implementation.
Thanks.
Assuming you can update the Session class, you can abstract the storage of the properties in the Session class. In your current application you can create a simple in-memory storage, and in the web application you can create a web-session storage.
First define a session-value-provider, which you use in your current static Session class.
public interface ISessionValueProvider {
string CurrentUser { get; set; }
string CurrentDatabase { get; set; }
string CurrentCompanyProfile { get; set; }
string CurrentLanguage { get; set; }
}
public static class Session {
private static ISessionValueProvider _sessionValueProvider;
public static void SetSessionValueProvider(ISessionValueProvider provider) {
_sessionValueProvider = provider;
}
public static string CurrentUser {
get { return _sessionValueProvider.CurrentUser; }
set { _sessionValueProvider.CurrentUser = value; }
}
// Etc for the other props
}
Than for your current application, define a sesion value provider which uses memory to storage the values.
public class MemorySessionValueProvider: ISessionValueProvider {
public string CurrentUser {get; set; }
// Etc for the other props
}
To use it, create an instance and give it to the static session class. For instance, you can add this to your Main method.
Session.SetSessionValueProvider(new MemorySessionValueProvider());
Now for your web application, create a session value provider which uses the web-session.
public class WebSessionValueProvider: ISessionValueProvider {
private const string CURRENTUSERKEY = "CurrentUser"; // TODO: Change this if necessary
public string CurrentUser {
get { return (string)HttpContext.Current.Session[CURRENTUSERKEY]; }
set { HttpContext.Current.Session[CURRENTUSERKEY] = value; }
}
// Etc for the other props
}
And again, give an instance of this web-session-value-provider to the static session class. For instance, in the global.asax.
Session.SetSessionValueProvider(new WebSessionValueProvider);
I'd use IoC container (for example Castle Windsor) for this. Declare an interface, for example, IStateManager:
public interface IStateManager
{
T GetItem<T>(string key);
SetItem<T>(string key, T value);
}
Then, your implementation of the Session class will change like the following:
public static class Session
{
private static IStateManager _manager;
private static IStateManager Manager
{
get
{
if (_manager == null)
{
IStateManager m = null; // Get instance using IoC container
Interlocked.CompareExchange(ref _manager, m, null);
}
return _manager;
}
}
public static string CurrentUser
{
get { return Manager.GetItem<string>("CurrentUser"); }
set { Manager.SetItem<string>("CurrentUser", value); }
}
// The rest is similar
}
For WinForms, the implementation will just operate on a static instance, for ASP.NET you'd have a different implementation that maintains data in the session. The benefit is that you'll just have different installers for different environments and your code doesn't need to know about them at all (therefore, the logic won't be dependent on either WinForms or ASP.NET).
Also, this approach is testable (it's very easy to mock the IStateManager using Moq, for example).
I use more than one class and I need a... lets say Global storage for all the class and method.
Is it the right way to create a static class for storage?
public static class Storage
{
public static string filePath { get; set; }
}
Or is there other ways to do it?
If you really need to make your example a singleton then here is how you do it.
public class StorageSingleton
{
private static readonly StorageSingleton instance;
static StorageSingleton() {
instance = new Singleton();
}
// Mark constructor as private as no one can create it but itself.
private StorageSingleton()
{
// For constructing
}
// The only way to access the created instance.
public static StorageSingleton Instance
{
get
{
return instance;
}
}
// Note that this will be null when the instance if not set to
// something in the constructor.
public string FilePath { get; set; }
}
The way to call and set the singleton is the following:
// Is this is the first time you call "Instance" then it will create itself
var storage = StorageSingleton.Instance;
if (storage.FilePath == null)
{
storage.FilePath = "myfile.txt";
}
Alternatively you can add into the constructor the following to avoid null reference exception:
// Mark constructor as private as no one can create it but itself.
private StorageSingleton()
{
FilePath = string.Empty;
}
Word of warning; making anything global or singleton will break your code in the long run. Later on you really should be checking out the repository pattern.
You could consider using the Singleton design pattern:
Implementing Singleton in c#
eg.
using System;
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
You should have a look at the repository pattern:
http://martinfowler.com/eaaCatalog/repository.html
One way of implementing this pattern is through the use of ORM's s.a. NHibernate:
https://web.archive.org/web/20110503184234/http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx
Applying Singleton to your original class:
public class Storage
{
private static Storage instance;
private Storage() {}
public static Storage Instance
{
get
{
if (instance == null)
{
instance = new Storage();
}
return instance;
}
}
public string FilePath { get; set; }
}
usage:
string filePath = Storage.Instance.FilePath;
I love seeing that implementation of singleton in C#.
public class Singleton
{
public static readonly Singleton instance;
static Singleton()
{
instance = new Singleton();
}
private Singleton()
{
//constructor...
}
}
C# guarantees that your instance wont be overriden and your static constructor guarantees that you WILL have your static property instantiated before the first time it's used.
Bonus: It's threadsafe as per language design for static constructors, no double checked locking :).