How to, using dependency injection, get configuration from multiple sources? - c#

I'm using Simple Injector, but maybe what I need is more of a conceptual answer.
Here's the deal, suppose I have an interface with my application settings:
public interface IApplicationSettings
{
bool EnableLogging { get; }
bool CopyLocal { get; }
string ServerName { get; }
}
Then, one would usually have a class which implements IApplicationSettings, getting each field from a specified source, for instance:
public class AppConfigSettings : IApplicationSettings
{
private bool? enableLogging;
public bool EnableLogging
{
get
{
if (enableLogging == null)
{
enableLogging = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableLogging"];
}
return enableLogging;
}
}
...
}
HOWEVER! Let's say I want to get EnableLogging from app.config, CopyLocal from database, and ServerName from another implementation which gets the current computer name. I want to be able to mix-match my app configuration without having to create 9 implementations, one for each combination.
I'm assuming that I can't pass any parameters because the interfaces are resolved by the injector (container).
I thought of this, initially:
public interface IApplicationSettings<TEnableLogging,TCopyLocal,TServerName>
where TEnableLogging : IGetValue<bool>
where TCopyLocal : IGetValue<bool>
where TServerName : IGetValue<string>
{
TEnableLogging EnableLog{get;}
TCopyLocal CopyLocal{get;}
TServerName ServerName{get;}
}
public class ApplicationSettings<TEnableLogging,TCopyLocal,TServerName>
{
private bool? enableLogging;
public bool EnableLogging
{
get
{
if (enableLogging == null)
{
enableLogging = Container.GetInstance<TEnableLogging>().Value
}
return enableLogging;
}
}
}
However, with this I have one main problem: How do I know how to create an instance of TEnableLogging (which is a IGetValue<bool>)? Oh, assume that IGetValue<bool> is an interface which has a Value property, which will be implemented by the concrete class. But the concrete class may need some specifics (like what's the name of the key in app.config) or not (I may simply want to return always true).
I'm relatively new to dependency injection, so maybe I'm thinking in a wrong way. Does anyone have any ideas on how to accomplish this?
(You may answer using another DI library, I won't mind. I think I just need to grab the concept of it.)

You are definitely heading the wrong way here.
Some years ago I built an application that contained an interface much like your IApplicationSettings. I believe I named it IApplicationConfiguration, but it contained all application's configuration values as well.
Although it helped me make my application testable at first, after some time the design started to get in the way. A lot of implementations depended on that interface, but it kept changing a lot and with it the implementation, and the test version.
Just like you I implemented some lazy loading, but this had a terrible down side. When one of the configuration values was missing, I only found out that it did when the value was called for the first time. This resulted in a configuration that was hard to verify.
It took me a couple of iterations of refactoring to find out what the core of the problem was. Big interfaces are a problem. My IApplicationConfiguration class was violating the Interface Segregation Principle and the result was poor maintainability.
In the end I found out that this interface was completely useless. Besides violating the ISP, those configuration values described an implementation detail and instead of making an application wide abstraction, it is much better to supply each implementation directly with the configuration value they need, and only the values they need.
When you do this, the easiest thing to do is to wrap those values into a Parameter Object (even if it is just one value), and inject those configuration values into the constructor. Here's an ecample:
var enableLogging =
Convert.ToBoolean(ConfigurationManager.AppSettings["EnableLogging"]);
container.RegisterSingleton(new LoggerSettings(loggingEnabled: enableLogging));
In this case, LoggerSettings is a configuration object specific to Logger, which requires it as constructor argument.
When doing this, the enableLogging value is read just once from the configuration file and is done so during application startup. This makes it fast and makes it fail at application startup when the value is missing.

Related

Use ExpandoObject to create a 'fake' implementation of an interface - adding methods dynamically

A brainteaser for you!
I am developing a modular system, in such a way that module A could need module B and module B could also need module A. But if module B is disabled, it will simply not execute that code and do nothing / return null.
A little bit more into perspective:
Let's say InvoiceBusinessLogic is within module "Core". We also have a "Ecommerce" module which has a OrderBusinessLogic. The InvoiceBusinessLogic could then look like this:
public class InvoiceBusinessLogic : IInvoiceBusinessLogic
{
private readonly IOrderBusinessLogic _orderBusinessLogic;
public InvoiceBusinessLogic(IOrderBusinessLogic orderBusinessLogic)
{
_orderBusinessLogic = orderBusinessLogic;
}
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.UpdateOrderStatus(invoice.OrderId);
}
}
So what I want is: When the module "Ecommerce" is enabled, it would actually do something at the OrderBusinessLogic. When not, it would simply not do anything. In this example it returns nothing so it can simply do nothing, in other examples where something would be returned, it would return null.
Notes:
As you can probably tell, I am using Dependency Injection, it is a ASP.NET Core application so the IServiceCollection takes care of defining the implementations.
Simply not defining the implementation for IOrderBusinessLogic will cause a runtime issue, logically.
From a lot of research done, I do not want to make calls to the container within my domain / logic of the app. Don't call the DI Container, it'll call you
These kind of interactions between modules are kept to a minimum, preferably done within the controller, but sometimes you cannot get around it (and also in the controller I would then need a way to inject them and use them or not).
So there are 3 options that I figured out so far:
I never make calls from module "Core" to module "Ecommerce", in theory this sounds the best way, but in practice it's more complicated for advanced scenarios. Not an option
I could create a lot of fake implementations, depending on the configuration decide on which one to implement. But that would of course result in double code and I would constantly have to update the fake class when a new method is introduced. So not perfectly.
I can build up a fake implementation by using reflection and ExpandoObject, and just do nothing or return null when the particular method is called.
And the last option is what I am now after:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
dynamic expendo = new ExpandoObject();
IOrderBusinessLogic fakeBusinessLogic = Impromptu.ActLike(expendo);
services.AddTransient<IOrderBusinessLogic>(x => fakeBusinessLogic);
}
By using Impromptu Interface, I am able to successfully create a fake implementation. But what I now need to solve is that the dynamic object also contains all the methods (mostly properties not needed), but those ones are easy to add. So currently I am able to run the code and get up until the point it will call the OrderBusinessLogic, then it will, logically, throw an exception that the method does not exist.
By using reflection, I can iterate over all the methods within the interface, but how do I add them to the dynamic object?
dynamic expendo = new ExpandoObject();
var dictionary = (IDictionary<string, object>)expendo;
var methods = typeof(IOrderBusinessLogic).GetMethods(BindingFlags.Public);
foreach (MethodInfo method in methods)
{
var parameters = method.GetParameters();
//insert magic here
}
Note: For now directly calling typeof(IOrderBusinessLogic), but later I would iterate over all the interfaces within a certain assembly.
Impromptu has an example as follows:
expando.Meth1 = Return<bool>.Arguments<int>(it => it > 5);
But of course I want this to be dynamic so how do I dynamically insert the return type and the parameters.
I do understand that a interface acts like a contract, and that contract should be followed, I also understand that this is an anti-pattern, but extensive research and negotiations have been done prior to reaching this point, for the result system we want, we think this is the best option, just a little missing piece :).
I have looked at this question, I am not really planning on leaving .dll's out, because most likely I would not be able to have any form of IOrderBusinessLogic usable within InvoiceBusinessLogic.
I have looked at this question, but I did not really understand how TypeBuilder could be used in my scenario
I have also looked into Mocking the interfaces, but mostly you would then need to define the 'mocking implementation' for each method that you want to change, correct me if I am wrong.
Even tough the third approach (with ExpandoObject) looks like a holy grail, I foster you to not follow this path for the following reasons:
What guarantees you that this fancy logic will be error-free now and at every time in the future ? (think: in 1 year you add a property in IOrderBusinessLogic)
What are the consequences if not ? Maybe an unexpected message will pop to the user or cause some strange "a priori unrelated" behavior
I would definitely go down the second option (fake implementation, also called Null-Object) even though, yes it will require to write some boilerplate code but ey this would offer you a compile-time guarantee that nothing unexpected will happen at rutime !
So my advice would be to do something like this:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
}
else
{
services.AddTransient<IOrderBusinessLogic, EmptyOrderBusinessLogic>();
}
}
For as long as there is no other answer for the solution I am looking for, I came up with the following extension:
using ImpromptuInterface.Build;
public static TInterface IsModuleEnabled<TInterface>(this TInterface obj) where TInterface : class
{
if (obj is ActLikeProxy)
{
return default(TInterface);//returns null
}
return obj;
}
And then use it like:
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.IsModuleEnabled()?.UpdateOrderStatus(invoice.OrderId);
//just example stuff
int? orderId = _orderBusinessLogic.IsModuleEnabled()?.GetOrderIdForInvoiceId(invoice.InvoiceId);
}
And actually it has the advantage that it is clear (in the code) that the return type can be null or the method won't be called when the module is disabled. The only thing that should be documented carefully, or in another way enforced, that is has to be clear which classes do not belong to the current module. The only thing I could think of right now is by not including the using automatically, but use the full namespace or add summaries to the included _orderBusinessLogic, so when someone is using it, it is clear this belongs to another module, and a null check should be performed.
For those that are interested, here is the code to correctly add all fake implementations:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
//just pick one interface in the correct assembly.
var types = Assembly.GetAssembly(typeof(IOrderBusinessLogic)).GetExportedTypes();
AddFakeImplementations(services, types);
}
using ImpromptuInterface;
private static void AddFakeImplementations(IServiceCollection services, Type[] types)
{
//filtering on public interfaces and my folder structure / naming convention
types = types.Where(x =>
x.IsInterface && x.IsPublic &&
(x.Namespace.Contains("BusinessLogic") || x.Namespace.Contains("Repositories"))).ToArray();
foreach (Type type in types)
{
dynamic expendo = new ExpandoObject();
var fakeImplementation = Impromptu.DynamicActLike(expendo, type);
services.AddTransient(type, x => fakeImplementation);
}
}

Override WebConfigurationManager.AppSettings["SomeProperty"] dynamically during execution

I have a code like that:
// can't make any changes at that class
class MyClass
{
void SomeMethod()
{
// some code ...
var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
// some code ...
}
}
I can't change that code, but I need that WebConfigurationManager.AppSettings["SomeProperty"] return different values depending on some external conditions (for example, depending on user role). So I'm looking for some way to override accessing to that property. In that override method I would check user role and
return appropriate value.
Is there any way to do that?
I found that question: Is there a way to override ConfigurationManager.AppSettings? but it seems that it's not suitable for me, because here value of WebConfigurationManager.AppSettings["SomeProperty"] set once when application starts. And I need to do it dynamically.
In MVC, in order to simplify the testing and mocking, I tend to use customized object for all the common classes, like Request, Session and ConfigManager, referenced through interfaces.
You basically don't need to realize classes from scratch obviously, so your implementation can be a wrapper which is actually using the .net class under the hood, but which gives also the chance to insert some custom logic in the middle, like in your case.
Therefore, you can create a wrapper of the webconfigurationManager, with a method like GetAppConfig(key) containing your own logic.
Playing with the concept of dependency injection is then easy enough having this class available wherever you need it.
Therefore to make a simple example:
//this will be injected
public MyControllerCtor(IConfig cfg)
public interface IConfig
{
string GetAppConfig(string key);
}
public class myConfig:IConfig
{
public string GetAppConfig(string key)
{
//your logic
var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
//your logic
return yourCustomAppSetting;
}
}
Big advantage of this approach is that if you wanted to store your config in a database or a service, and change your code, you simply need to change your interface implementation and the inject the new instance.
If you can't change the code that is reading the AppSettings, then there is no way to do what you want. WebConfigurationManager is not pluggable or replacable externally.
You'll have to change the code.
No, of course not.
If you can't change the class, then you can't change the behavior. There's no general reason why Microsoft would have placed an "override" capability inside of WebApplicationManager. Usually, one is expected to be able to change ones class, or else to design it properly so that it can be overridden the right way.
It sounds like you need to do some logic after retrieving the value from the web.config. If the logic modifies the value itself, you could always store a format string in the web.config instead.
Here's an example using a connection string setting. I'm using a format string to populate the server name at runtime:
<add name="sqlconnection" connectionString="Server={0}\SQLEXPRESS;Database=xxx;Trusted_Connection=True;"/>
And then I'm using this logic:
string connect = ConfigurationManager.ConnectionStrings["sqlconnection"].ConnectionString;
if (!String.IsNullOrEmpty(connect))
{
//check to see if the connection string needs to be set at runtime
if (connect.Contains("{0}"))
connect = String.Format(connect, HttpContext.Current.Server.MachineName);
}
return connect;
EDIT: If you can't edit the class directly, I would consider creating a partial class to implement this.
If you make direct changes to Web.config they will be effective only during the next request, and as I understand, this is not the desired effect.
You can not directly affect WebConfigurationManager.AppSettings["SomeProperty"], and that's the desired behavior, as the AppSettings as configurations are something static.
To achieve an effect close to what you desire, I'd suggest you to use the HttpContext.Current.Items collection, in which you will initialize in Application_BeginRequest to a certain value if conditions are met or default to WebConfigurationManager.AppSettings["SomeProperty"] otherwise.
Than, instead of accessing WebConfigurationManager.AppSettings["SomeProperty"] you will be accessing HttpContext.Current.Items["SomeProperty"].

Add a parameter, or create a new method?

Let's say I have a long established repository like this:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts();
}
It's been around for ages, and the GetDonuts method does what it says. Then one day I need to add a new screen that shows all the donuts in the database, and it turns out that the method has a hidden feature - it filters out all donuts where stale = true. But on my new screen, I want to show all of them, even the stale ones! What is the best approach here?
Assuming that this method is used all over the place, and the default behaviour needs to stay the same, is it best to add a new method called GetAllDonuts that doesn't do the filtering, or should I just add a onlyFresh parameter onto the GetDonuts method?
I'm guessing its just down to judgement, but I'm wondering if there are any more informed answers out there?
I would overload the method creating a new overload that takes the showStale parameter and then modify the old method to use the new overload passing false for the parameter value.
The interface would look like:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts();
public IEnumerable<Donut> GetDonuts(bool showStale);
}
Or if you're using .NET 4.0, you can use an optional parameter:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts(bool showStale = false);
}
Why not use an optional parameter? This way you don't break existing code:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts(bool onlyFresh);
}
Implementation:
public IEnumerable<Donut> GetDonuts(bool onlyFresh = false)
{
if (onlyFresh)
// do stuff
else
// do other stuff
}
This really comes down to personal preference, to some extent...
If you have the ability to change the API, I would (personally) rename the current method in a way that makes it obvious that it is not returning all Donut instances. My expectation would be that a repository's GetDonuts method would get all of the donuts. This could be doing via a parameter, or a different name, at your discretion.
That being said, a method overload taking the extra parameter is probably the best option moving forward, if keeping compatibility is critical. (This depends a lot on who and where this API is used...)
Depending on the circumstancs, one might consider introducing a property for accessing the donuts.
interface IDonutRepository
{
IEnumerable<Donut> Donuts { get; }
.. or ..
IQueryable<Donut> Donuts { get; }
}
It's fairly easy to implement this interface if you're using a Linq-savvy ORM like Entity Framework or NHibernate.
The old GetDonuts method could be renamed GetFreshDonuts(), or you could refactor calls to it into the form:
repository.Donuts.Where(x => !x.Stale)
One of the growing trends in software
design is separating interface from
implementation. The principle is about
separating modules into public and
private parts so that you can change
the private part without coordinating
with other modules. However, there is
a further distinction—the one between
public and published interfaces. This
distinction is important because it
affects how you work with the
interface.
http://www.martinfowler.com/ieeeSoftware/published.pdf

Design for Cross-Platform Classes in C#

Summary: I want to know the best design for creating cross-platform (eg. desktop, web, and Silverlight) classes in C#, with no duplication of code, with the pros and cons of each design.
I'm often writing new, useful classes for one application domain; there's no reason why they won't work across domains. How can I structure my code to make it ideally cross-platform?
For example, let's say I wanted to make a generic "MyTimer" class with an interval and on-tick event. In desktop, this would use the built-in .NET timer. In Silverlight, I would use a DispatchTimer.
Design #1 might be "create a class and use pre-processor directives for conditional compilation," eg. "#IF SILVERILGHT ...". However, this leads to code that is less understandable, readable, and maintainable.
Design #2 might be "create subclasses called DesktopTimer and SilverlightTimer and consume those from MyTimer." How would that work?
While this is a trivial case, I may have more complicated classes that, for example, consume platform-specific classes (IsolatedStorage, DispatchTimer, etc.) but aren't directly replacing them.
What other designs/paradigms can I use?
I would suggest writing Interfaces that you would simply implement for your platform specific code. Then, the interfaces assure that your code will respect the contracts given by your interface, otherwise there will be a code break (if one member is not implemented).
Besides, within this library where resides your specific timer classes, to stick to your example, I would create a class for each platform, thus using the DispatchTimer for Silverlight, and the built-in .NET timer for the desktop version.
In the end, you would end up using only one interface that only its implementers know how to deal with the contract specifically to your underlying platform.
EDIT #1
Conditonal design is not an option for a good design. Here is a tool that will help you deal with the Dependancy Injection, that is called Unity Application Block, and is used to deal with such scenario like yours.
You only use an XML configuration that is very versatile to "tell" what has to be instantiated when this or that interface is needed. Then, the UnityContainer consults with the configuration you have made, and instantiate the right class for you. This assures good design approach and architecture.
EDIT #2
I'm not very familiar with Dependency Injection, and not at all familiar with Unity Application Block. Can you point to some resources or explain these a bit further?
Microsoft Enterprise Library 5.0 - April 2010;
Microsoft Unity 2.0 – April 2010;
Microsoft Unity 2.0 Documentation for Visual Studio 2008;
Are there good tutorial/walkthroughs for unity that don't use configuration files? (SO question on the topic that should provide valuable hints to start with Unity);
Specifying Types in the Configuration File;
Walkthrough: The Unity StopLight QuickStart;
Walkthrough: The Unity Event Broker Extension QuickStart.
I think these resources shall guide you through your learnings. If you need further assistance, please let me know! =)
EDIT #3
But anyway, the StopLight quickstart [...] seems to imply that the dependency mapping of interface to concrete class is done in code (which won't work for me).
In fact, you can do both code and XML dependency mapping, the choice is yours! =)
Here are some example that you should perhaps inspire from to make the StopLight quickstart use the XML configuration instead of the coded mapping.
Testing Your Unity XML Configuration;
Using Design-Time Configuration;
Source Schema for the Unity Application Block.
If this doesn't help you get through, let me know. I shall then provide a simple example using XML dependency mapping. =)
1) Interfaces with platform-specific class in their own assemblies: ITimer in a shared assembly, and a "WebAssembly" containing WebTimer, for example. Then the "WebAssembly.dll", or "DesktopAssembly.dll" are on-demand loaded. This turns it into more of a deployment/configuration issue, and everything compiles. Dependency Injection or MEF become a great help here.
2) Interfaces (again), but with conditional compilation. This makes it less of a deployment issue, and more of a compilation problem. WebTimer would have #ifdef WEB_PLATFORM around it, and so on.
Personally, I'd lean to #1 - but in a complicated application, most likely you'll end up having to use both because of slight changes in the available parts of the .net framework between silverlight and everything else. You may even want different behavior in core parts of your app just for the performance issues.
I think interfaces are a good choice here (defining what a timer will do without actually implementing it)
public interface ITimer
{
void CreateTimer(int _interval, TimerDelegate _delegate);
void StopTimer();
// etc...
} // eo interface ITimer
From this, you derive your concrete timers:
public class DesktopTimer : ITimer
{
} // eo DesktopTimer
public class SilverlightTimer : ITimer
{
} // eo class SilverlightTimer
public class WebTimer : Timer
{
} // eo class WebTimer
Then comes the fun part. How do we create the right timer? Here you could implement some kind of platform-factory that returned the right timer depending on what platform it is running on. Here is a quick and dirty idea (I would make it more dynamic than this, and perhaps implement one factory for multiple kinds of classes, but this is an example)
public enum Platform
{
Desktop,
Web,
Silverlight
} // eo enum Platform
public class TimerFactory
{
private class ObjectInfo
{
private string m_Assembly;
private string m_Type;
// ctor
public ObjectInfo(string _assembly, string _type)
{
m_Assembly = _assembly;
m_Type = _type;
} // eo ctor
public ITimer Create() {return(AppDomain.CurrentDomain.CreateInstanceAndUnwrap(m_Assembly, m_Type));}
} // eo class ObjectInfo
Dictionary<Platform, ObjectInfo> m_Types = new Dictionary<PlatForm, ObjectInfo>();
public TimerFactory()
{
m_Types[Platform.Desktop] = new ObjectInfo("Desktop", "MyNamespace.DesktopTimer");
m_Types[Platform.Silverlight] = new ObjectInfo("Silverlight", "MyNameSpace.SilverlightTimer");
// ...
} // eo ctor
public ITimer Create()
{
// based on platform, create appropriate ObjectInfo
} // eo Create
} // eo class TimerFactory
As I mentioned above, I would not have a factory for every time of object, but make a generic platform-factory that could handle timers, containers and whatever else you want. This is just an example.
The Model-View-Presenter pattern is a really good approach if you want to separate all of your user interface logic from the actual GUI framework you are using. Read Michael Feather's article "The Humble Dialog Box" to get an excellent explanation of how it works:
http://www.objectmentor.com/resources/articles/TheHumbleDialogBox.pdf
The original article was made for C++, if you want a C# example, look here:
http://codebetter.com/blogs/jeremy.miller/articles/129546.aspx
The Pros are:
you will make your GUI logic resusable
your GUI logic becomes applicable for unit testing
The Cons:
if your program does not need more than one GUI framework, this approach produces more lines-of-code, and you have to deal with more complexity, since you have to decide all through your coding which parts of your code belong into the view and which into the presenter
Go with all OOD you know. I'd suggest creating platform-agnostic (Windows, Mono/destkop, web) domain model. Use abstract classes to model platform-dependant stuff (like the Timer). Use Dependency Injection and/or Factory patterns to use specific implementations.
EDIT: at some point you have to specify what concrete classes to use, but using the abovementioned patterns can bring all that code into one place without using conditional compilation.
EDIT: an example of DI/Factory. Of course you can use on of existing frameworks, which will give you more power and expressivenes. For the simple example it seems like an overkill, but the more complicated the code, the bigger the gain of using the patterns.
// Common.dll
public interface IPlatformInfo
{
string PlatformName { get; }
}
public interface PlatformFactory
{
IPlatformInfo CreatePlatformInfo();
// other...
}
public class WelcomeMessage
{
private IPlatformInfo platformInfo;
public WelcomeMessage(IPlatformInfo platformInfo)
{
this.platformInfo = platformInfo;
}
public string GetMessage()
{
return "Welcome at " + platformInfo.PlatformName + "!";
}
}
// WindowsApp.exe
public class WindowsPlatformInfo : IPlatformInfo
{
public string PlatformName
{
get { return "Windows"; }
}
}
public class WindowsPlatformFactory : PlatformFactory
{
public IPlatformInfo CreatePlatformInfo()
{
return new WindowsPlatformInfo();
}
}
public class WindowsProgram
{
public static void Main(string[] args)
{
var factory = new WindowsPlatformFactory();
var message = new WelcomeMessage(factory.CreatePlatformInfo());
Console.WriteLine(message.GetMessage());
}
}
// MonoApp.exe
public class MonoPlatformInfo : IPlatformInfo
{
public string PlatformName
{
get { return "Mono"; }
}
}
public class MonoPlatformFactory : PlatformFactory
{
public IPlatformInfo CreatePlatformInfo()
{
return new MonoPlatformInfo();
}
}
public class MonoProgram
{
public static void Main(string[] args)
{
var factory = new MonoPlatformFactory();
var message = new WelcomeMessage(factory.CreatePlatformInfo());
Console.WriteLine(message.GetMessage());
}
}
As others have sugested, interfaces are the way to go here. I would alter the interface from sugestion Moo-Juice suggestion slightly...
`
//Why is this block not formated like code???
public interface ITimer{
void StopTimer(); // etc...
void StartTimer(); // etc...
TimeSpan Duration {get;} // eo interface ITimer
}`
Now you would need to get the ITimer into your class that is using it. The most timple way to do this is called dependency injection. The most common approach to achieve this is called constructor injection.
So when creating a class that needs a timer you pass a timer into the class when creating one.
Basically you do:
var foo = new Foo(new WebTimer());
Since that will get complicated quite fast, you can utilize some helpers. This pattern is called inversion of control. There are some frameworks that will help you, like the ninject or castle windsor.
Both are inversion of control (IOC) containers. (Thats the secret sauce)
Basically you "register" your timer in the IOC, and also register your "Foo". When you need a "Foo", you ask your IOC Container to create one. The container looks at the constructor, finds that it needs a ITimer. It will then create an ITimer for you, and pass it into the constructor, and finally hand you the complete class.
Inside you class you dont need to have any knowledge about the ITimer, or how to create it, since all that was moved to the outside.
For different Applications you now only need to register the correct components, and you are done...
P.s.: Be carefull and dont confuse the IOC Container with a service locator...
Links:
http://ninject.org/download
http://www.castleproject.org/container/index.html
http://www.pnpguidance.net/Category/Unity.aspx
Why not have configuration section which will tell your library about the platform of the host application. This you have to set only once in your application to the host config file (web.config or app.config), and rest you can use using Factory method as suggested by Moo-Juice. You can use platform detail over entire functionality of the library.

What do you look for in a dependency to determine if it should be an injected dependency?

I am having difficult figuring out when a dependency should be injected. Let's just work with a simple example from my project:
class CompanyDetailProvider : ICompanyDetailProvider {
private readonly FilePathProvider provider;
public CompanyDetailProvider(FilePathProvider provider) {
this.provider = provider;
}
public IEnumerable<CompanyDetail> GetCompanyDetailsForDate(DateTime date) {
string path = this.provider.GetCompanyDetailFilePathForDate(date);
var factory = new DataReaderFactory();
Func<IDataReader> sourceProvider = () => factory.CreateReader(
DataFileType.FlatFile,
path
);
var hydrator = new Hydrator<CompanyDetail>(sourceProvider);
return hydrator;
}
}
(Not production quality!)
ICompanyDetailProvider is responsible for providing instances of CompanyDetails for consumers. The concrete implementation CompanyDetailProvider does it by hydrating instances of CompanyDetail from a file using a Hydrator<T> which uses reflection to populate instances of T sourced from an IDataReader. Clearly CompanyDetailProvider is dependent on DataReaderFactory (which returns instances of OleDbDataReader given a path to a file) and Hydrator. Should these dependencies be injected? Is it right to inject FilePathProvider? What qualities do I examine to decide if they should be injected?
I evaluate dependencies' points of use through the intent/mechanism lens: is this code clearly communicating its intent, or do I have to extract that from a pile of implementation details?
If the code indeed looks like a pile of implementation details, I determine the inputs and outputs and create an entirely new dependency to represent the why behind all the how. I then push the complexity into the new dependency, making the original code simpler and clearer.
When I read the code in this question, I clearly see the retrieval of a file path based on a date, followed by an opaque set of statements which don't clearly communicate the goal of reading an entity of a certain type at a certain path. I can work my way through it but that breaks my stride.
I suggest you raise the level of abstraction of the second half of the calculation, after you get the path. I would start by defining a dependency which implements the code's inputs/outputs:
public interface IEntityReader
{
IEnumerable<T> ReadEntities<T>(string path);
}
Then, rewrite the original class using this intention-revealing interface:
public sealed class CompanyDetailProvider : ICompanyDetailProvider
{
private readonly IFilePathProvider _filePathProvider;
private readonly IEntityReader _entityReader;
public CompanyDetailProvider(IFilePathProvider filePathProvider, IEntityReader entityReader)
{
_filePathProvider = filePathProvider;
_entityReader = entityReader;
}
public IEnumerable<CompanyDetail> GetCompanyDetailsForDate(DateTime date)
{
var path = _filePathProvider.GetCompanyDetailsFilePathForDate(date);
return _entityReader.ReadEntities<CompanyDetail>(path);
}
}
Now you can sandbox the gory details, which become quite cohesive in isolation:
public sealed class EntityReader : IEntityReader
{
private readonly IDataReaderFactory _dataReaderFactory;
public EntityReader(IDataReaderFactory dataReaderFactory)
{
_dataReaderFactory = dataReaderFactory;
}
public IEnumerable<T> ReadEntities<T>(string path)
{
Func<IDataReader> sourceProvider =
() => _dataReaderFactory.CreateReader(DataFileType.FlatFile, path);
return new Hydrator<T>(sourceProvider);
}
}
As shown in this example, I think you should abstract the data reader factory away and directly instantiate the hydrator. The distinction is that EntityReader uses the data reader factory, while it only creates the hydrator. It isn't actually dependent on the instance at all; instead, it serves as a hydrator factory.
I tend to be on the more liberal side of injecting dependencies so I would definitely want to inject both IDataReader to get rid of the new DataFactoryReader and the Hydrator. It keeps everything more loosely coupled which of course makes it easier to maintain.
Another benefit that is easy to attain right away is better testability. You can create mocks of your IDataReader and Hydrator to isolate your unit tests to just the GetCompanyDetailsForDate method and not have to worry about what happens inside the datareader and hydrator.
How to determine if a class should use dependency injection
Does this class require an external dependency?
If yes, inject.
If no, has no dependency.
To answer "Is it right to inject FilePathProvider?" yes it is right.
Edit: For clarification any external dependency is where you call to an unrelated but dependent class, especially when it involves a physical resources such as reading File Pathes from disk, but this also implies any kind of service or model class that does logic indepedent to the core functionality of the class.
Generally this be surmised with anytime you call the new operator. In most circumstances you want to refactor away all usages of the new operator when it has to deal with any class other than a data transfer object. When the class is internal to the usage location then a new statement can be fine if it reduces complexity such as the new DataReaderFactory() however this does appear to be a very good candidate for constructor injection also.

Categories

Resources