Universally accessible class/object with constructor parameters - c#

I'm creating a platform/foundation component (set of .NET assemblies) that is going to be responsible for accessing (reading/writing) configuration values. This component is to be used by other components that are going to be created on the platform.
I want this component to be easy to use for consumers, but also have high testability and maintainability. In my current design I have a static class (ConfigurationManager) that contains some methods (for example GetKeyValueSetting). This ConfigurationManager class is special in that it can either get the configuration values from the local .NET .config file, but also from a SharePoint list (some of the components are hosted in a Shared SharePoint environment) and even from another shared config value store. The Manager should be able to read from multiple locations in a prioritized fashion:
if running on SharePoint: 1. SharePointSettingsProvider, 2. SharedStoreSettingsProvider
if not running on SharePoint: 1. ConfigFileSettingsProvider 2. SharedStoreSettingsProvider
I know that a static class creates a lot of issues in regards to testability, extensibility etc so I don't want to use that. My next alternative is a Singleton, but in regards to the aforementioned -ilities this is not a much better solution. Any ideas for a better solution?
My current design is as follows:
public static class ConfigurationManager
{
// internal for testability
internal IEnumerable<ISettingsProvider> SettingsProviders {get;set;}
// internal for testability
internal ISettingsProviderFactory ProvidersFactory {get;set;}
public static string GetKeyValueSetting(string key)
{
}
}
public interface ISettingsProvider
{
string GetKeyValueSetting(string key);
}
public class ConfigFileSettingsProvider : ISettingsProvider
{
}
public class SharePointSettingsProvider : ISettingsProvider
{
}
public class SharedStoreSettingsProvider : ISettingsProvider
{
}
public interface ISettingsProviderFactory
{
IEnumerable<ISettingsProvider> GetProviders();
}

Why not this:
public abstract class ConfigurationManager
{
public abstract string GetKeyValueSetting(string key);
public static ConfigurationManager GetInstance()
{
return GetInstance(GetDefaultSettingProvider(), GetDefaultProviderFactory());
}
public static ConfigurationManager GetInstance(ISettingsProvider provider, IProviderFactory factory)
{
return new InternallyVisibleConfigurationManagerImplementation(provider, factory);
}
}
This has a lot of benefits:
ConfigurationManager is abstract, so calling code can Mock it easily
It's easy to get a default implementation
Calling assemblies can easily configure it with different providers and factories
Calling assemblies cannot couple to a concrete type
You can change the specific implementation type easily (i.e., maybe you want a caching proxy so you don't need to make expensive calls to sharepoint as often)
You keep all your easy testability
You can refactor to a singleton or other variations of life-cycle management without changing client code
If callers really hate this, and don't mind their unit tests calling sharepoint sites sometimes, you could add a convenience method like this:
public static string GetKeyValueSetting(string key)
{
return GetInstance().GetKeyValueSetting(key);
}
EDIT
To use a couple of stores, create a class like this:
internal class OrderedCompositeSettingProvider : ISettingProvider
{
private readonly ISettingProvider[] _providers;
private OrderedCompositeSettingProvider(ISettingProvider[] providers)
{
_providers = providers;
}
internal static ISettingProvider GetInstance(params ISettingProvider[] providers)
{
return new OrderedCompositeSettingProvider(providers)
}
public string GetKeyValueSetting(string key)
{
foreach(var provider in _providers)
{
var setting = provider.GetKeyValueSetting(key);
if(!string.IsNullOrEmpty(setting)) return setting;
}
return string.empty;
}
}
Then in the ConfigurationManager factory method:
public static ConfigurationManager GetInstance()
{
return GetInstance(GetAppropriateProvider(), GetDefaultProviderFactory());
}
private static ISettingsProvider GetAppropriateProvider()
{
if(ShouldUseSharepoint())
return OrderedCompositeSettingProvider.GetInstance(new SharepointProvider(), new StoredSettingsProvider());
return OrderedCompositeSettingProvider.GetInstance(new ConfigFileProvider(), new StoredSettingsProvider());
}

Related

Dependency Injection - Using a static dependency field instead of injecting to each object

What is wrong with having the dependency object as a static field in a static class instead of injecting it to each object that depends on it through constructor?
public static class Dependencies
{
public static IUsersRepository Users;
...
}
//Use in a method that depends on Users Repository
var users = Dependencies.Users.GetUsers();
VS.
public class UserController
{
private IUsersRepository _users;
public UserController(IUsersRepository repo)
{
this._users = repo;
}
public List<User> GetCustomUsers()
{
var users = this._users.GetUsers();
...
}
}
There is a DI pattern called "Ambient Context" you can use to do this.
It allows you to avoid passing a cross-cutting concern all the time, but it still allows you to Unit Test things.
The canonical example is a DateTime provider:
public abstract class TimeProvider {
private static TimeProvider current =
DefaultTimeProvider.Instance;
public static TimeProvider Current {
get { return TimeProvider.current; }
set {
if (value == null) {
throw new ArgumentNullException("value");
}
TimeProvider.current = value;
}
}
public abstract DateTime UtcNow { get; }
public static void ResetToDefault() {
TimeProvider.current = DefaultTimeProvider.Instance;
}
}
Where an implementation might look like this:
public class DefaultTimeProvider : TimeProvider {
private readonly static DefaultTimeProvider instance =
new DefaultTimeProvider();
private DefaultTimeProvider() { }
public override DateTime UtcNow {
get { return DateTime.UtcNow; }
}
public static DefaultTimeProvider Instance {
get { return DefaultTimeProvider.instance; }
}
}
Code would use TimeProvider.Current to access the DateTime rather than using DateTime directly.
The default concrete implementation returns the usual DateTime.UtcNow. However, for unit testing you can use a special test implementation and set TimeProvider.Current to it before running the unit tests.
See this page (where that code comes from) for more information.
Note that you should only use this pattern for truly cross-cutting concerns such as DateTime, security, logging and so on.
Suppose that a UserController would like to use an instant IUsersRepository and another UserController would like to use an instance of a different IUserRepository implementation, then you can't do this with static dependencies.
To be honest, the police aren't going to come knocking on your door if you do, but taken to it's logical conclusion (i.e. an application of any appreciable size) you end up with a more difficult to maintain "spaghetti code" codebase.
Mostly, coupling, and things like the SOLID principles. You are tightly coupling to the Dependency class, when ideally DI prevents this by building object graphs for you, injecting the dependencies, so those objects have no knowledge (i.e. are not coupled) to the implementation that provides them. If you're using a DI container and a singleton lifestyle, then you've essentially got what you describe - static fields. But with a container (even the "containerless" style containers that are becoming popular) you get more flexibility and the hard things are done for you.
There are a few cases where using DI, particularly via a container, are probably a bad idea (logging, generating new Guid values, getting the current date). You can solve those few cases with the "ambient context" solution (see Matthew Watson's answer for more details).

Is Service Locator an anti pattern in a pluggable architecture?

I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)

How to create global constant variables in C# for the entire application

I have a table that contains system configuration (ie. system_name, system_time_zone.....)
I am trying to identify the best approach to read the configuration automaticly and have the value ready to read in any form in my application.
Basically, I want to read the configuration from the table and then set them as a constant variables. When the application loads I can re-use them in any form.
How would I be able to do this in C#?
Well, you could create a singleton class which would read the configuration on startup.
Personally, however, I would investigate dependency injection. There are lots of DI frameworks in .NET, and that way you'll have code which is easier to test, because it's given the configuration rather than it fetching it from somewhere which may be ugly to fake.
You may also want to consider separating the configuration out into different related parts, and only inject the parts of configuration that are relevant to a class into that class. For example, you might want one class holding all of the database-related settings, another for all the email-related settings (if it needs to send or retrieve emails) etc. That way it makes it obvious which aspects of configuration each part of your system depends on, which improves maintainability.
You could implement the Singleton Pattern, like this:
public class AppConfiguration
{
private static readonly Lazy<AppConfiguration> Instance
= new Lazy<AppConfiguration>(LoadConfiguration, LazyThreadSafetyMode.PublicationOnly);
public static AppConfiguration Current
{
get { return Instance.Value; }
}
public string SystemName { get; private set; }
public int SystemTimeZone { get; private set; }
private AppConfiguration() {}
private static AppConfiguration LoadConfiguration()
{
var configuration = new AppConfiguration();
configuration.LoadFromDatabase();
return configuration;
}
private void LoadFromDatabase()
{
using (var db = new AppEntities())
{
// Load configuration from DB
this.SystemName = ""; // Load properties
}
}
}
And you can use it like this:
var systemName = AppConfiguration.Current.SystemName;
You could create a Singleton class for that:
public class ConfigurationSettings
{
private ConfigurationSettings _instance;
public int Setting1 { get; set; }
public static ConfigurationSettings GetInstance()
{
return _instance;
}
// call this method once to load up all the data (at startup)
public static void InitializeSingleInstance()
{
_instance = new ConfigurationSettings();
}
private ConfigurationSettings()
{
// load from db / files / ...
}
}
Getting a setting would then go like:
int setting = ConfigurationSettings.GetInstance().Setting1;

Swapping between versions of a webservice c#

I wish to maintain code that calls an existing webservice but make it so I can call a newer version of the same webservice (based on a config setting). I'll need to have different namespaces as the webservice is the same name. Does anyone have any best practice patters for accomplishing this?
Thanks,
Steven
The "Factory" pattern (and probably "Facade" pattern) are your friends here.
So, given you have two services that implement a common method or set of methods you can do this kind of thing to make a general service factory:
I'm assuming you have two services called ServiceOld and ServiceNew (they could have the same name and sit in different namespaces as is your case). And that these services share a common method public string GetName();.
First I create an interface that embodies these services:
public interface IService
{
string GetName();
}
Now, if you can modify the service code directly you could implement this interface directly on your services, or you could perhaps inherit down your services and implement this interface. I'm going to assume that your services are both not under your control and are sealed. So I would implement two wrapper (or facade) classes.
public class ServiceOldWrapper : IService
{
private ServiceOld _inner = new ServiceOld();
public string GetName()
{
return _inner.GetName();
}
}
public class ServiceNewWrapper : IService
{
private ServiceNew _inner = new ServiceNew();
public string GetName()
{
return _inner.GetName();
}
}
Now I can write the factory class.
public class ServiceFactory
{
public IService CreateService()
{
if (configValueThatYouNeedToRead == "Old")
{
return new ServiceOldWrapper();
}
else
{
return new ServiceNewWrapper();
}
}
}
Now calling this becomes simple:
var sf = new ServiceFactory();
var s = sf.CreateService();
var name = s.GetName();
You probably will need to handle cleaning up your services a little better than I have so your code will be a bit more complicated, but this should get you started.

Fake ASMX Web Service Call

I built a .NET ASMX web service connecting to an SQL Server database. There is a web service call GetAllQuestions().
var myService = new SATService();
var serviceQuestions = myService.GetAllQuestions();
I saved the result of GetAllQuestions to GetAllQuestions.xml in the local application folder
Is there any way to fake the web service call and use the local xml result?
I just want to take the contents of my entire sql table and have the array of objects with correlating property names automatically generated for me just like with LINQ to SQL web services.
Please keep in mind that I am building a standalone Monotouch iPhone application.
Use dependency injection.
//GetSATService returns the fake service during testing
var myService = GetSATService();
var serviceQuestions = myService.GetAllQuestions();
Or, preferably, in the constructor for the object set the SATService field (so the constructor requires the SATService to be set. If you do this, it will be easier to test.
Edit: Sorry, I'll elaborate here. What you have in your code above is a coupled dependency, where your code creates the object it is using. Dependency injection or the Inversion of Control(IOC) pattern, would have you uncouple that dependency. (Or simply, don't call "new" - let something else do that - something you can control outside the consumer.)
There are several ways to do this, and they are shown in the code below (comments explain):
class Program
{
static void Main(string[] args)
{
//ACTUAL usage
//Setting up the interface injection
IInjectableFactory.StaticInjectable = new ConcreteInjectable(1);
//Injecting via the constructor
EverythingsInjected injected =
new EverythingsInjected(new ConcreteInjectable(100));
//Injecting via the property
injected.PropertyInjected = new ConcreteInjectable(1000);
//using the injected items
injected.PrintInjectables();
Console.WriteLine();
//FOR TESTING (normally done in a unit testing framework)
IInjectableFactory.StaticInjectable = new TestInjectable();
EverythingsInjected testInjected =
new EverythingsInjected(new TestInjectable());
testInjected.PropertyInjected = new TestInjectable();
//this would be an assert of some kind
testInjected.PrintInjectables();
Console.Read();
}
//the inteface you want to represent the decoupled class
public interface IInjectable { void DoSomething(string myStr); }
//the "real" injectable
public class ConcreteInjectable : IInjectable
{
private int _myId;
public ConcreteInjectable(int myId) { _myId = myId; }
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", _myId, myStr);
}
}
//the place to get the IInjectable (not in consuming class)
public static class IInjectableFactory
{
public static IInjectable StaticInjectable { get; set; }
}
//the consuming class - with three types of injection used
public class EverythingsInjected
{
private IInjectable _interfaceInjected;
private IInjectable _constructorInjected;
private IInjectable _propertyInjected;
//property allows the setting of a different injectable
public IInjectable PropertyInjected
{
get { return _propertyInjected; }
set { _propertyInjected = value; }
}
//constructor requires the loosely coupled injectable
public EverythingsInjected(IInjectable constructorInjected)
{
//have to set the default with property injected
_propertyInjected = GetIInjectable();
//retain the constructor injected injectable
_constructorInjected = constructorInjected;
//using basic interface injection
_interfaceInjected = GetIInjectable();
}
//retrieves the loosely coupled injectable
private IInjectable GetIInjectable()
{
return IInjectableFactory.StaticInjectable;
}
//method that consumes the injectables
public void PrintInjectables()
{
_interfaceInjected.DoSomething("Interface Injected");
_constructorInjected.DoSomething("Constructor Injected");
_propertyInjected.DoSomething("PropertyInjected");
}
}
//the "fake" injectable
public class TestInjectable : IInjectable
{
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", -10000, myStr + " For TEST");
}
}
The above is a complete console program that you can run and play with to see how this works. I tried to keep it simple, but feel free to ask me any questions you have.
Second Edit:
From the comments, it became clear that this was an operational need, not a testing need, so in effect it was a cache. Here is some code that will work for the intended purpose. Again, the below code is a full working console program.
class Program
{
static void Main(string[] args)
{
ServiceFactory factory = new ServiceFactory(false);
//first call hits the webservice
GetServiceQuestions(factory);
//hists the cache next time
GetServiceQuestions(factory);
//can refresh on demand
factory.ResetCache = true;
GetServiceQuestions(factory);
Console.Read();
}
//where the call to the "service" happens
private static List<Question> GetServiceQuestions(ServiceFactory factory)
{
var myFirstService = factory.GetSATService();
var firstServiceQuestions = myFirstService.GetAllQuestions();
foreach (Question question in firstServiceQuestions)
{
Console.WriteLine(question.Text);
}
return firstServiceQuestions;
}
}
//this stands in place of your xml file
public static class DataStore
{
public static List<Question> Questions;
}
//a simple question
public struct Question
{
private string _text;
public string Text { get { return _text; } }
public Question(string text)
{
_text = text;
}
}
//the contract for the real and fake "service"
public interface ISATService
{
List<Question> GetAllQuestions();
}
//hits the webservice and refreshes the store
public class ServiceWrapper : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From WebService");
//this would be your webservice call
DataStore.Questions = new List<Question>()
{
new Question("How do you do?"),
new Question("How is the weather?")
};
//always return from your local datastore
return DataStore.Questions;
}
}
//accesses the data store for the questions
public class FakeService : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From Fake Service (cache):");
return DataStore.Questions;
}
}
//The object that decides on using the cache or not
public class ServiceFactory
{
public bool ResetCache{ get; set;}
public ServiceFactory(bool resetCache)
{
ResetCache = resetCache;
}
public ISATService GetSATService()
{
if (DataStore.Questions == null || ResetCache)
return new ServiceWrapper();
else
return new FakeService();
}
}
Hope this helps. Good luck!
when you say fake the call, are you just testing the client side?
you could use fiddler, intercept the request and return the local xml file to the client. No messing around with your client code then.
To elaborate on Audie's answer
Using DI would get you what you want. Very simply you would create an interface that your real object and your mock object both implement
public interface IFoo
{}
Then you would have your GetSATService method return either a MockSATSerivce or the real SATService object based on your needs.
This is where you would use a DI container (some object that stores interface to concrete type mappings) You would bootstrap the container with the types you want. So, for a unit test, you could contrstruct a mock container that registers the MockSATService as the implementer of the IFoo interface.
Then you would as the container for the concrete type but interface
IFoo mySATService = Container.Resolve<IFoo>();
Then at runtime you would just change out the container so that it bootstraps with the runtime types instead of the mock types but you code would stay the same (Because you are treating everything as IFoo instead SATService)
Does that make sense?
Over time I found that an interesting way to do this is by extracting an interface and creating a wrapper class. This adapts well to a IoC container and also works fine without one.
When testing, create the class passing a fake service. When using it normally, just call the empty constructor, which might simply construct a provider or resolve one using a config file.
public DataService : IDataService
{
private IDataService _provider;
public DataService()
{
_provider = new RealService();
}
public DataService(IDataService provider)
{
_provider = provider;
}
public object GetAllQuestions()
{
return _provider.GetAllQuestions();
}
}

Categories