I am working on updating a legacy application that is absolutely rife with Singleton classes. A perfect example would be the SnmpConnector class:
public SnmpConnector
{
public static IEnumerable<string> HostIpAddresses
{
...
}
private static SnmpConnector instance;
public static SnmpConnector Instance
{
if (instance == null)
instance = new SnmpConnector();
return instance;
}
private SnmpConnector()
{
foreach (string IpAddress in HostIpAddresses)
{
...
}
}
...
}
The goal of this update is to increase testability of the codebase, and as such I want to get rid of the Singletons. I've already abstracted away the data source of the SnmpConnector to either get data from a test database or from querying a live server:
public interface ISnmpDataSource
{
public DataTable MacTable
{
get;
private set;
}
public DataTable PortTable
{
get;
private set;
}
...
}
public TestSnmpDataSource : ISnmpDataSource
{
public FileInfo DataSource
{
get;
private set;
}
...
}
public SnmpDataSource : ISnmpDataSource
{
public List<string> HostIpAddresses
{
get;
private set;
}
...
}
public SnmpConnector
{
public SnmpConnector(ISnmpDataSource DataSource)
{
...
}
...
}
Now, I'm trying to test these components and running into the problem that probably caused SnmpConnector to be a Singleton in the first place: it takes an ungodly amount of time to test the SnmpDataSource. It turns out that fetching the MAC table and Port table from live switches takes somewhere between 10 and 20 seconds. I've already written 13 unit tests for this particular class, so it takes over two minutes for just these tests to complete. As annoying as this is, it gets worse once these updates get published to our original codebase. With this new refactoring, there is nothing stopping a programmer from creating and discarding an SnmpDataSource repeatedly.
Now, the data from these tables is largely static; the old Singleton and the new SnmpDataSource both maintain a cache that was only updated every four hours. Will I have to make SnmpDataSource a Singleton to prevent this problem?
Use dependency injection, and either pass the SnmpDataSource into anything that needs it, or potentially pass in a Func<SnmpDataSource> which can create the instance lazily as necessary.
Is your goal that the SnmpDataSource should update itself, or that callers will get a new version after a few hours?
You could try wrapping/decorating the SnmpDataSource with a cache-aware version that implements the same interface, then inject the cache-aware version.
*edit -- or you could do what Jon suggested where the factory Func does the caching instead (it will return a new instance or a cached version depending on when the last one was created). Same thing, slightly different implementation. Jon's version probably makes more sense.
public CachedSnmpDataSource : ISnmpDataSource
{
private DateTime m_lastRetrieved;
private TimeSpan m_cacheExpiryPeriod;
private List<string> m_hostIpAddresses;
private Func<SnmpDataSource> m_dataSourceCreator
public CachedSnmpDataSource(Func<SnmpDataSource> dataSourceCreator, TimeSpan cacheExpiryPeriod)
{
m_dataSourceCreator = dataSourceCreator;
m_cacheExpiryPeriod = cacheExpiryPeriod;
}
public List<string> HostIpAddresses
{
get
{
if(!IsRecentCachedVersionAvailable())
{
CreateCachedVersion();
}
return new List<string>(m_hostIpAddresses);
}
private bool IsRecentCachedVersionAvailable()
{
return m_hostIpAddresses != null &&
(DateTime.Now - m_lastRetrieved) < m_cacheExpiryPeriod;
}
private void CreateCachedVersion()
{
SnmpDataSource dataSource = m_dataSourceCreator();
m_hostIpAddresses = dataSource.HostIpAddresses;
m_lastRetrieved = DateTime.Now;
}
}
...
}
After a couple of iterations, I've ended up with a neat solution to this problem. I'm going to leave the accepted answer as is, but this is what I ultimately used:
ISnmpDataSource is responsible for fetching data, as before.
The SnmpConnector knows to only query if its own cache is invalid.
A static Factory class maintains a Dictionary<ISnmpDataSource, SnmpConnector>. There is a static BuildSnmpConnector(ISnmpDataSource) method based on this dictionary.
Using the library now looks like this:
IEnumerable<string> IpAddresses = ...;
string SqlConString = #"...";
ISnmpDataSource Switches = new SnmpDataSource(IpAddresses, SqlConStr);
SnmpConnector instance = Factory. BuildSnmpConnector(Switches);
I had a few problems with how I implemented GetHashCode and Equals for the ISnmpDataSource implementations, but formalizing a definition of equality pretty much fixed all those problems.
I'm pretty happy with the final result; the Factory class is responsible for limiting instantiation, while the SnmpConnector is responsible for caching query results, while the ISnmpDataSource is responsible for actually running queries. I'm sure there is a better organization out there, but this one is clean enough for use.
Related
I've seen adding public properties advocated in the Art of Unit Testing (by Roy Osherove) to help get at and setup awkward (or internal) collaborators/collaborations used by a SUT, and have used this technique myself to good effect. (Also I have seen a similar approach using an additional constructor instead)
Likewise, a testing isolation framework (such as Moq) can provide an alternative and using Moq a Callback can be used to help set up an awkward collaborator/collaboration.
The trade off's that I have experienced here are that:
Using a public field introduces additional items into the SUT, with slightly cleaner testing code
Versus
A SUT uncluttered by additional items to make it testable and slightly more clunky testing code (the callback code is not the prettiest).
In my situation and, owing to a constraint on what is a command AND should be a query - a query which could return stubbed data, there is no easy way to administer the collaboration in the SUT (without the aforementioned mechanisms)
A collaborator in the SUT updates an object passed by reference in a command, this looks lik: (repeated in code examples a little later)
var warehouse = new Warehouse(); // internal to Order
_repo.Load(warehouse); // Warehouse is filled by reference
EDIT: I have contrived an example which has design problems - Warehouse and Order are overly intimate, an application service could be use to orchastrate interactions etc. The Nub of the problem is that I have very little control over how the Warehouse gets populated. I am using a framework which uses a command to hydrate an object by reference. This IS the problem, I know, but unfortunately I am constrained by it. So the real focus of this question is not about a redesign but purely which method, callback or public field would be preferable, if this is all we had to work with.
The code examples below are both working examples using Moq and NUnit.
For the purposes of time I have omitted adding an application service to orchestrate the example use case ( which is basically fill an Order from a compliant Warehouse - based on Fowler's Mocks aren't Stubs example ). Also both approaches take a classic approach to unit testing, asserting state as opposed to verifying behaviour and this isn't my intended focus of the question.
Before going on, I do have a preference but I would be interested to see what other people suggest or prefer.
So firstly the public property approach, code and tests: (smarts in the use of the Func<>)
public class Order
{
private readonly IWarehouseRepo _repo;
public int Items { get; private set; }
public Func<Warehouse> WarehouseBuilder { get; set; }
public Order(IWarehouseRepo repo)
{
_repo = repo;
}
public void AddOrderItems(int numberOfItems)
{
var warehouse = WarehouseBuilder();
_repo.Load(warehouse);
warehouse.RemoveStock(numberOfItems);
Items += numberOfItems;
}
}
public class Warehouse
{
public int Items { get; set; }
public void RemoveStock(int numberOfItems)
{
Items -= numberOfItems;
}
}
[TestFixture]
public class Given_A_Warehouse_With_20_Items
{
private Order _order;
private Mock<IWarehouseRepo> _warehouseRepo;
private Warehouse _warehouse;
[SetUp]
public void When_An_Order_Is_Placed()
{
_warehouseRepo = new Mock<IWarehouseRepo>();
_warehouse = new Warehouse() { Items = 20 };
_order = new Order(_warehouseRepo.Object);
_order.WarehouseBuilder = () => _warehouse;
_order.AddOrderItems(5);
}
[Test]
public void Then_The_Order_Now_Has_5_Items()
{
Assert.That(_order.Items, Is.EqualTo(5));
}
[Test]
public void Then_The_Warehouse_Now_Has_15_Items()
{
Assert.That(_warehouse.Items, Is.EqualTo(15));
}
}
public interface IWarehouseRepo
{
void Load(Warehouse warehouse);
}
And secondly the callback approach, code and tests: (Smarts in the callback)
public class Order
{
private readonly IWarehouseRepo _repo;
public int Items { get; private set; }
public Order(IWarehouseRepo repo)
{
_repo = repo;
}
public void AddOrderItems(int numberOfItems)
{
var warehouse = new Warehouse();
_repo.Load(warehouse);
warehouse.RemoveStock(numberOfItems);
Items += numberOfItems;
}
}
public class Warehouse
{
public int Items { get; set; }
public void RemoveStock(int numberOfItems)
{
Items -= numberOfItems;
}
}
[TestFixture]
public class Given_A_Warehouse_With_20_Items
{
private Order _order;
private Mock<IWarehouseRepo> _warehouseRepo;
private Warehouse _warehouse;
[SetUp]
public void When_An_Order_Is_Placed()
{
_warehouseRepo = new Mock<IWarehouseRepo>();
_warehouseRepo.Setup(repo => repo.Load(It.IsAny<Warehouse>())).Callback<Warehouse>(warehouseArgument =>
{
warehouseArgument.Items = 20;
_warehouse = warehouseArgument;
}
);
_order = new Order(_warehouseRepo.Object);
_order.AddOrderItems(5);
}
[Test]
public void Then_The_Order_Now_Has_5_Items()
{
Assert.That(_order.Items, Is.EqualTo(5));
}
[Test]
public void Then_The_Warehouse_Now_Has_15_Items()
{
Assert.That(_warehouse.Items, Is.EqualTo(15));
}
}
public interface IWarehouseRepo
{
void Load(Warehouse warehouse);
}
Adding public state to make testing easier is a valid technique when used correctly. Likewise living with complex tests, while letting the production code remain intact is also completely valid. Both can be wrong also, so a third option is to also look at your design. In reality which you chose depends on a variety of factors. Beware anyone who states the one true way.
Public State
Adding public state is nice because it's easy, but poor because it wouldn't exist there if you weren't writing automated tests against the code. Usually this makes sense when you get hold of some legacy code and adding some additional fields isn't a big deal. If you make these read only you can limit the reach of these fields also. Interestingly in software this technique isn't used as much as it should be. In the field of hardware, circuitry and the like are physically shipped with testing components still attached. These are never used once shipped.
Complex Tests
This tends to be the most common form you see. Messy or complex tests that do anything to get the tests to work. The nice thing here is at least the design isn't compromised with public fields just for the sake of testing, but the downside as you've noted is somewhat complex and ugly tests. You can offset this by using SUT builders or simply refactoring your tests as you go, such as extracting helpers to hide the messier parts. If you do this you can at least retain the benefits of clean code and cleaner tests.
Look at the Design
Sadly the most underused but would have solved your problem. Tests hard to write? Then your design can do with improving. If the tests for new code requires public state to make it easy to test? Then your design can do with improving.
Your Example
In your case it makes sense to go with the lesser of two evils. The complex tests using the callback would be my personal recommendation. Simply when you weigh up the pros and cons of above. Yeah the test looks complex, and due to the tooling your using it has some rather gnarly syntax but it's not the end of the world.
If you really cannot change how you load the warehouse assuming either a 3rd party dependency or other reason there is another option. Create your own warehouse repository that would hide the command aspect and return a new warehouse instance. You would now have a query which you could then stub easily and side step the problems above. Sadly this would introduce a new component so you need to weigh this up. If you can change the component to become a query, I'd recommend that first.
The Func isn't really public state in my opinion. It's not a field. It's a rather novel hack around the fact the design is wrong.
How about neither. Bear with me as I walk through my thought process here. This looks more like an issue with design. I am reminded of an article I read recently about how new is glue in that Order should not couple itself with having to new up an instance of Warehouse or be responsible for exposing some way to configure it (SRP). I initially thought of adding a new dependency, something like a factory.
public interface IFactory<T> where T: class {
T Create();
}
but then though against it as that would just be adding more gunk into the class. My thoughts were focused on avoiding the introduction of additional items into the SUT.
The thing is,...based on your example the SUT needed a way to be able to create a Warehouse and load it up but not be responsible for it while keeping it self relatively lean. Then I started thinking...Whose job/responsibility is it to manage Warehouse...
The IWarehouseRepo jumped out at me and then I remembered a pattern I saw in the Entity Framework's IDbSet.
public interface IWarehouseRepo {
Warehouse Create();
void Load(Warehouse warehouse);
}
Couldn't shake the feeling that I was overthinking the problem and ended up with something like this
//My job is to provide a loaded warehouse to those who want one.
public interface IWarehouseProvider {
Warehouse GetWarehouse();
}
which would provide an already loaded Warehouse to be used by the order. Which is all it really wanted in the first place.
public class Order {
private readonly IWarehouseProvider provider;
public int Items { get; private set; }
public Order(IWarehouseProvider provider) {
this.provider = provider;
}
public void AddOrderItems(int numberOfItems) {
//get a pre-loaded warehouse
var warehouse = provider.GetWarehouse();
warehouse.RemoveStock(numberOfItems);
Items += numberOfItems;
}
}
The order shouldn't care about creating or Loading a warehouse. It just wants a Warehouse to fulfill it's order. Why over complicate things. We had a good arrangement, now you want to get clingy. (I digress)
[TestFixture]
public class Given_A_Warehouse_With_20_Items
{
private Order _order;
private Mock<IWarehouseProvider> _warehouseProvider;
private Warehouse _warehouse;
[SetUp]
public void When_An_Order_Is_Placed() {
_warehouse = new Warehouse() { Items = 20 };
_warehouseProvider = new Mock<IWarehouseProvider>();
_warehouseProvider.Setup(provider => provider.GetWarehouse()).Returns(_warehouse);
_order = new Order(_warehouseProvider.Object);
_order.AddOrderItems(5);
}
[Test]
public void Then_The_Order_Now_Has_5_Items() {
Assert.That(_order.Items, Is.EqualTo(5));
}
[Test]
public void Then_The_Warehouse_Now_Has_15_Items() {
Assert.That(_warehouse.Items, Is.EqualTo(15));
}
}
For me the thing that eventually lit the light bulb was you test. I decided to work backwards with what you were trying to test.
Given A Warehouse With 20 Items
Sure the thought process may be flawed, but the Order class just wanted a loaded Warehouse and could care less about how it was created or loaded. I could be spinning top in mud as this still looks like the Factory pattern to me.
Edit. A potential provider can then look like this
public class DefaultWarehouseProvider : IWarehouseProvder {
private readonly IWarehouseRepo repo;
public DefaultWarehouseProvider(IWarehouseRepo repo) {
this.repo = repo;
}
public Warehouse GetWarehouse() {
var warehouse = new Warehouse
repo.Load(warehouse);
return warehouse;
}
}
Does this look like what you had before? Yes, yes it does. The thing now is that it is abstracted away into its own domain allowing its dependents to carry on with their tasks without concerns for how the sausage is made. You isolate/quarantine your constraints so that they don't go around spreading their code smell disease. :)
I am wondering if this class is thread safe
Can I access the Currencies property's getter without performing a lock?
Should I lock my access to the Currencies property within the GetLiveExchangeRates() method?
public class CurrencyManager
{
public static List<CurrencyModel> Currencies { get; private set; }
private static readonly object LockObj = new object();
public CurrencyManager()
{
Currencies = new List<CurrencyModel>();
}
public static void GetLiveExchangeRates()
{
lock (LockObj)
{
Currencies = GetSomeFooLiveDataFromInternet();
}
}
}
EDIT
How would you refactor it?
If you must stick with a static class, I would refactor the class like this:
public class CurrencyManager
{
private static readonly IEnumerable<CurrencyModel> currencies = Enumerable<CurrencyModel.Empty();
private static readonly object LockObj = new object();
public static void RefreshLiveExchangeRates()
{
lock (LockObj)
{
CurrencyManager.currencies = GetSomeFooLiveDataFromInternet();
}
}
public static IEnumerable<CurrencyModel> GetCurrencies()
{
return CurrencyManager.currencies;
}
}
Renaming the method to something that better describes what is actually happening. When you call it GetLiveExchangeRates, I would expect it to return back the exchange rates rather than void. I'd then delete the constructor all together and create a GetCurrencies() method that returns the collection, or an empty one if the collection is null. It seems like the collection you are exposing, Currencies, should not be exposed publicly as a List as that allows consumers to change it. You haven't explained what the point of the collection is, so I'm making an assumption by trying to infer what is happening through your naming conventions.
If I were to write this, I would probably hide this behind a service instead. Removing the need for the static class. You hold a reference to the exchange rates in your view model/controller/service what-have-you. When you need to refresh them, hit the service again.
Service
public class CurrencyService
{
public IEnumerable<CurrencyModel> GetLiveExchangeRates()
{
return GetSomeFooLiveDataFromInternet();
}
}
Consumer (viewmodel/controller etc)
public class MyController
{
private IEnumerable<CurrencyModel> currentRates;
public MyController()
{
// Instance a new service; or provide it through the constructor as a dependency
var currencyService = new CurrencyService();
this.currentRates = currencyService.GetLiveExchangeRates();
}
}
Then your consuming class would use the collection it fetched from the service. If it wants to, it can pass around that collection to other objects that depend on it. When you feel the collection is stale, you re-fetch them from the service. At this point, you probably wouldn't need to do any locking because only the consumer can use the property and can control when it can and will change the property. This lets multiple instances query for the latest exchange rates without having to do a lock and make everyone queue up to receive them.
Ideally, I'd like to see it passed in as a dependency via the constructor, hidden behind an interface, with the rates refreshed at the time they are needed. So instead of fetching the rates in the constructor, I would fetch them lazily when needed. This would let you do the work async (assuming your real implementation is async).
Edit
If you are storing the collection in the static class for caching purposes, you could store the collection in the service, and always return the collection. The only time a new set of exchange rates is returned is when you clear the cache.
public class CurrencyService
{
private static IEnumerable<CurrencyModel> currencyRates;
private static object ratesLock = new object();
public IEnumerable<CurrencyModel> GetLiveExchangeRates()
{
if (currencyRates == null)
{
lock (ratesLock)
{
currencyRates = GetSomeFooLiveDataFromInternet();
}
}
return currencyRates;
}
public void ClearRates()
{
currencyRates = null;
}
}
This is more or less an implementation change. Your controller/viewmodel would continue to hit GetLiveExchangeRates(), but it would only fetch them once from your external service. Each time afterwards it would just return the cache. You only pay the locking fee once, then when other objects hit your service concurrently you don't pay the locking fee again.
I am currently working with a codebase that uses the Anaemic Domain Model, and I am trying to move more logic into the domain models in a move towards a Domain Model and Domain Driven Design, but I am struggling with the following problem.
I have a domain model called Job which looks like this,
public class Job
{
private DateTime _someOtherDate;
private DateTime _lastUpdated;
// this may be called from many different services
public void SetLastUpdated()
{
_lastUpdated = DateTime.UtcNow;
}
}
At some point in time, during the processing a job I want to set the job's last updated date to that specific point in time. To do this I have created a public setter for it as you can see above.
An issue arises when I am pulling back the Job from the database in my repository, as I now have no public setter for this field because I have restricted that to SetLastUpdated().
Can someone please advise on how I could allow this property to be set in the repository implementation when retrieving the job, but not from the service where it is restricted to calling SetLastUpdated().
Update 1) I have updated the question as using start date was a bad example.
Update 2) From the answers given, the only way I can see this being done is by not using AutoMapper in the repository, adding a constructor onto the Job class for setting _lastUpdated, and using this when constructing the Job to be returned in the repository's job retrieval method.
As I see it, you have various options.
Option 1
Assuming that your repository has two methods:
public IEnumerable<Job> ReadAll() { ... }
public int CreateJob(Job job) { ... }
You can give the Job class two constructors, one that takes a DateTime and one that does not.
public class Job
{
public Job(DateTime startDate)
{
this.StartDate = startDate;
}
public Job() : this(DateTime.UtcNow)
{
}
public DateTime StartDate { get; private set; }
}
This does not prevent the service from calling the "wrong" constructor, but at least it communicates the option of calling it without the startDate to the caller.
Option 2
Work with two different Job classes.
Your repository could look like this instead:
public IEnumerable<Job> ReadAll() { ... }
public int CreateJob(NewJob newJob) { ... }
And the NewJob class could look like:
public class NewJob
{
public NewJob()
{
this.StartDate = DateTime.UtcNow;
}
public DateTime StartDate { get; private set; }
}
This communicates intent better, because the repository's Create method only accepts an instance of NewJob so the user of the model will be forced to create a NewJob instead of a Job.
Option 3
Ignore the StartDate in the repostory's Create method and always set it to DateTime.UtcNow within the method. Or even go so far as to create an Insert trigger in the database that sets it.
A common approach is to use constructors for this
public class Job
{
private DateTime _startDate;
public void Job()
{
_startDate = DateTime.UtcNow;
}
public void Job(DateTime dt)
{
// check DateTime kind, this could be source of a bug
if(dt.Kind != DateTimeKind.Utc) throw new ...
_startDate = dt;
}
}
You have to expose this method/property one way or another. If repository can set it, you can set it from other locations. If you try to be smart about this (you could, for example by using interfaces), you'd get into a risk of overengineering.
One of the primary reasons you're doing DDD is to take advantage of the managed mutability that can be provided by encapsulation. That is always going to start with the constructor.
In general, this is the type of work an ORM is specifically designed to perform, however it can also take advantage of any existing DTOs that would have been mapped onto the domain object by using the memento pattern:
public Job() {
_lastUpdated = DateTime.UtcNow;
// ...
}
public Job(JobData data) {
_lastUpdated = data.LastUpdated;
//...
}
re: AutoMapper - it's been a while since I used it, but it should be possible for you to instruct it to access fields using reflection in the configuration.
On a multithread application (ASP.NET MVC) I need to have a global settings class which contains constants and values taken from Web.Config.
I would like to have this class static, as singleton ... And locked?
public static class Settings {
public static LoggerSettings Logger;
public static MailerSettings Mailer;
public class LoggerSettings {
public String Levels { get { return ConfigurationManager.AppSettings["Logger.Levels"]; } }
public const String Report = "team#xyz.com";
} // LoggerSettings
public class MailerSettings {
public String Contact { get { return ConfigurationManager.AppSettings["Mailer.Contact"]; } }
} // MailerSettings
}
I think I should implement a double lock? No?
I am not sure the best way to do this. Could I, please, get some help?
Thank You,
Miguel
I would like to have this class static, as singleton
To implement a singleton correctly in C#, see Jon Skeet's excellent summary of what does and does not work:
http://csharpindepth.com/Articles/General/Singleton.aspx
I think I should implement a double lock? No?
No. Double-checked locking is a low-lock technique and therefore insanely dangerous on weak memory model hardware. The moment you stray even the slightest from a "blessed" pattern you have abandoned all hope of the program behaving predictably.
The only circumstances under which I would use double-checked locking are when all of the following are true:
Is there is extensive empirical evidence that single-checked locking produces poor performance?
Let's suppose single-checked performance is unacceptable. Single-checked locking usually produces bad performance due to contention, so step one is eliminate the contention. Can you eliminate the contention and get acceptable performance? I would only use double-checked locking if it was impossible to remove the contention or if the performance problem was caused by the several nanoseconds it takes to obtain an uncontended lock. In the latter case: wow, that's a fast program that those nanoseconds are the slowest thing, and wow, you have pretty serious performance requirements if you're counting individual nanoseconds.
Let's suppose that single-checked performance is unacceptable and cannot be fixed. Is there another low-lock technique, like using Interlocked.CompareExchange or Lazy<T> that has acceptable performance? At least you know that CompareExchange and Lazy<T> were written by experts and enforce memory barriers appropriately on all hardware. Don't use double-checked locking if there is a better tool already implemented.
Let's suppose that none of these tools give acceptable performance. Does double-checked locking give acceptable performance? If not then don't use it.
as I see, you only read the data. So you need not lock here IMO.
Use static constructor to init your variables, like Report (made it also static).
Take a look at Jon Skeet's article Implementing the Singleton Pattern in C#
Simplest and good enough option:
public sealed class Settings
{
private static readonly Settings instance = new Settings();
public LoggerSettings Logger { get; private set; }
public MailerSettings Mailer { get; private set; }
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Settings()
{
}
private Settings()
{
Logger = new LoggerSettings();
Mailer = new MailerSettings();
}
public static Settings Instance { get { return instance;} }
}
public class LoggerSettings {
public LoggerSettings()
{
Levels = ConfigurationManager.AppSettings["Logger.Levels"];
}
public String Levels { get; private set; }
public const String Report = "team#xyz.com";
}
// Mailer settings would look similar
As you are only reading data from this instance you don't need any locking. The singleton instance is created before any other thread can access it so no need to lock there also.
Usage:
Settings.Instance.Mailer.Contact
if you like it static and as Singleton, try it this way:
public static class Settings {
private static readonly object LockObject = new object();
private static LoggerSetting LoggerInstance;
public static LoggerSetting LoggerSettings {
get {
lock (LockObject) {
if (LoggerInstance == null)
LoggerInstance = new LoggerInstance();
return LoggerInstance;
}
}
}
public class LoggerSetting {
public String Levels {
get { return ConfigurationManager.AppSettings["Logger.Levels"]; }
}
public const String Report = "team#xyz.com";
}
}
and use it by:
string x = Settings.LoggerSEttings.Report;
if you'd still like to go ahead and have a singleton instance
public class MySettings{
private static Object lockObj = new Object();
private MySettings() {} // private .ctor
private static MySettings _instance;
public static MySettings MySingleSettings{
get{
if(_instance == null){
lock(lockObj){
if(_instance == null)
_instance = new MySettings();
}
}
return _instance;
}
}
I know that the standard singleton pattern is as follows:
Original
public class Singleton1
{
public static Singleton1 _Instance;
public static Singleton1 Instance
{
get
{
if (_Instance == null)
{
_Instance = new Singleton1();
}
return _Instance;
}
}
private Singleton1()
{
}
}
But it seems like this code is unnecessary. To me, you could accomplish the same thing with either of the following simple design patterns:
Version 2
public class Singleton2
{
public static readonly Singleton2 Instance = new Singleton2();
private Singleton2()
{
}
}
Version 3
public class Singleton3
{
static Singleton3()
{
}
}
To me, it seems like version 2 is the superior method of doing this because it allows you to pass in parameters (or not) yet still have a finite number of instance. My application is fairly latency/performance sensitive - do any of these patterns have a performance gain?
It would seem that while it will longer to access each one the first time because the object is being created. Also, it would seem that the original one is ever so slightly slower because it must check to see whether its backing field is null every time something else accesses it.
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
Fast, clean, thread-safe.
One problem with singletons implemented as static instances is that they make testing and mocking more difficult.
See this scenario:
public void BusinessLogicMethod()
{
var initialValue = MySingleton.Instance.GetInitialValue();
var processedValue = initialValue + specialSomething + businessLogic;
MySingleton.Instance.SaveProcessedValue(processedValue);
}
Now, let's say I want to write a unit-test for this method. Ideally, I want to write a test that specifies input and output and tests only the business logic. But with a static singleton, the method's implementation is tied to the singleton's implementation. Can I set the InitialValue easily at the beginning of the test, or is it dependent on other factors/DB access/whatever?
However, if I use a non-static singleton, coupled with some dependency injection or service locator pattern, I can build my function like this:
public void BusinessLogicMethod()
{
var singleton = ServiceLocator.Resolve<MySingleton>();
var processedValue = singleton.InitialValue + specialSomething + businessLogic;
singleton.SaveProcessedValue(processedValue);
}
and my test can go like this, using vaguely Moq-like mock syntax:
public void TestBusinessLogic()
{
MySingleton fakeSingleton = new Mock<MySingleton>();
fakeSingleton.Setup(s => s.InitialValue).Returns(5);
// Register the fake in the ServiceLocator
ServiceLocator.Register<MySingleton>(fakeSingleton.Object);
// Run
MyBusinessMethod();
// Assert
fakeSingleton.Verify (s => s.SaveProcessedValue()).Called(Exactly.Once);
}
without worrying about the REAL singleton implementation.
Singleton2 is not the same as Singleton1 as the Instance is not "lazy" evaluated. In Singleton1, Instance is created only when it is accessed and from then on the same one is used. In SingleTon2, the Instance is initialized with the class and before being actually accessed.
My favourite singleton implementation is this one:
http://www.codeproject.com/Articles/14026/Generic-Singleton-Pattern-using-Reflection-in-C
Make sure your .ctor is not public, which is the most common mistake, then, it is safely/fully reusable.
(I need to have a close look at Peter Kiss' one which looks nice too)
To answer your performance question, the time it takes to check whether the private field is null is negligible. Therefore I wouldn't be worrying about how it is implemented with regards to performance here.