Is this implementation of a central static class correct? - c#

So, I'm starting a new project, trying to implement a few things I've learnt over the last few years, the first of which is using Castle for IoC.
I want a central 'Core' class, which would be shared across numerous end projects (Console apps, websites). So I guess, two questions here:
a) Is this approach correct
b) Is my implementation correct.
I know this is a very small class, but I want to get it correct from the start.
public static class Global {
static IWindsorContainer _Container;
static int ContainerInitalised = 0;
static string ServicesFile;
public static IWindsorContainer Container{
get{
if (Interlocked.CompareExchange(ref ContainerInitalised, 1, 0) == 0) {
Collection<IWindsorInstaller> installers = new Collection<IWindsorInstaller> {
{ FromAssembly.InDirectory(new AssemblyFilter("Installers")) }
};
if (!String.IsNullOrWhiteSpace(ServicesFile)) {
installers.Add(Configuration.FromXmlFile(ServicesFile));
}
_Container = new WindsorContainer().Install(installers.ToArray());
}
return _Container;
}
}
public static void Initialise(string servicesFile) {
ServicesFile = servicesFile;
}
}

AS per David your idea go toward a ServiceLocator solution which is the worst way to use an IoC container.
Also abstracting IoC container with a common interface is a bad idea because you end up loosing special container features: speacially an interface not exposing a release method leads to a disaster using a mature IoC container such windosr which is based on RRR pattern.
The correct approach has been clearly described by Krzysztof on his NDC presentations
Plug the IoC container into your app using a factory as per MVC3 implementation
Do one Resolve only as soon as possible: a single Resolve for non web-app, one resolve per request for a web scenario
Release ALWAYS what you resolved

You might be able to clean it up a bit by taking a step toward a "service locator" implementation. (Indeed, there's a common library that does exactly this.)
For example, you can abstract the IoC container behind an interface and have a static factory that provides the current implementation (to replace your generic Global class and make it more targeted). Something like this:
public interface IoCContainer
{
object GetInstance(Type serviceType);
object GetInstance(Type serviceType, string key);
IEnumerable<object> GetAllInstances(Type serviceType);
T GetInstance<T>();
T GetInstance<T>(string key);
IEnumerable<T> GetAllInstances<T>();
}
public static class IoCContainerFactory
{
private static IoCContainer current;
public static IoCContainer Current
{
get
{
if (current == null)
throw new DomainException("IoC Container Not Initialized. This application must call a bootstrap method in an IoC implementation project.");
return current;
}
}
public static void Initialize(IoCContainer container)
{
current = container;
}
}
Then in another project I implement the IoCContainer interface (I use StructureMap, you use Castle... there are plenty of options). Also in that other project I have an Initializer class which will bootstrap the container implementation (since configuration is different for any implementation) and, as a last step, initialize this "global" factory:
IoCContainerFactory.Initialize(new IoCContainerImplementation(ObjectFactory.Container));
(In the case of the above line of code, IoCContainerImplementation is my implementation of the aforementioned interface, and ObjectFactory is from StructureMap and was just configured/bootstrapped in previous lines of code before this one.)
Of course, with this approach, there's a bit of a trade-off. By abstracting my IoC container behind a common interface, I can only do things which are common across many IoC container implementations. For my needs, all I want is to call a method to resolve dependencies. But other things like decorating classes/properties with attributes (if your choice of IoC container has that feature) would require either tightly coupling to that specific container or expanding this implementation to include custom attributes which make use of that feature in some way.

Related

Define custom autofacs with Unity (Container abstraction)?

In Ninject you can do
kernel.Bind(typeof(Func<,>)).ToMethod(CreateFunc).When(VerifyFactoryFunction);
This means with some magic and reflection you can do
public MyConstructor(Func<Type, IResult> factory) {
this.result = factory(typeof(SomeType));
}
Instead of
public MyConstructor(IUnityContainer container) {
this.result = container.Resolve(typeof(SomeType));
}
Is this possible with Unity? I did this extension method
public static void RegisterContainerAbstraction<TTo>(this IUnityContainer self)
{
self.RegisterInstance<Func<Type, TTo>>(t => (TTo)self.Resolve(t));
}
You need to call it for all types that you want to abstract the container for, like
container.RegisterContainerAbstraction<IResult>();
What Ninject allows is a bit a special feature and this is more of a functional approach. The DI libraries in .NET by default take a more object oriented approach which means that the support for creating and auto-wiring classes is usually pretty good, while the creation and currying of functions is supported poorly.
So, out of the box, there is nothing in Unity that will allow you to do this, but this can be easily solved by creating a custom interface and implementation:
// Abstraction: Part of your core library
public interface IFactory<TResult>
{
TResult Create(Type type);
}
// Implementation: Part of your composition root
private sealed CreateFuncFactory<TResult> : IFactory<TResult>
{
// Since we're in the Composition Root, its okay to depend
// on the container here. See: https://bit.ly/1mdaLYG
private readonly IUnityContainer container;
public CreateFuncFactory(IUnityContainer container) {
this.container = container;
}
public TResult Create(Type type) {
return (TResult)container.Resolve(type);
}
}
You can register this in Unity as follows:
container.RegisterType(typeof(IFactory<>), typeof(CreateFuncFactory<>));
Still however, if you apply Dependency Injection correctly, there is much less need for factory abstractions. They are still useful, but you probably need just a hand full in an application. So in that respect, instead of having one generic Func<,> or IFactory<T> abstraction, specify specific factories instead. This makes it much more obvious what is going on and since you should have a few factories this will not lead to lots of boilerplate code.

Possible bug with dependency injection on MvvmCross

I'm currently working on a cross platform (Android and iOS) using the brilliant MVVMCross and things are going pretty great with the application and no major hassles so far.
However today I've hit one that's causing me some problems. I'm a strong believer in separation of concerns and what I'm trying to do is to register a class as a lazy singleton implementer of two different interfaces. This is my App.cs in the PCL:
public class App : Cirrious.MvvmCross.ViewModels.MvxApplication
{
public override void Initialize()
{
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterAppStart<LoginViewModel>();
Mvx.LazyConstructAndRegisterSingleton<ISystemConfigProviderInitialiser, SystemConfigProvider>();
Mvx.LazyConstructAndRegisterSingleton<ISystemConfigProvider, SystemConfigProvider>();
}
}
The ISystemConfigProvider will have a number of readonly properties only and will be injected into viewmodels that need to read the system config.
The ISystemConfigProviderInitializer will be injected into the DataService (itself constructed by IoC) and has an Initialize() method that allows a poco to be passed in which sets all the properties mentioned for the ISystemConfigProvider
For completeness SystemConfigProvider is like this:
public class SystemConfigProvider: ISystemConfigProvider, ISystemConfigProviderInitialiser
{
public string Name {get;}
....
public string Z {get;}
public void Initialize(PocoObjToSetPropertiesAbove obj)
{
//set all properties
}
}
The problem I'm having is that the SystemConfigProvider class is getting created multiple times. twice, seemingly once per each interface which contradicts what I'm told by the MVVMCross wiki page about Service Location and Inversion of Control:
Technical Note> the lazy singleton implementation here is quite technical - it ensures that if a >class implements IOne and ITwo then the same instance will be returned when resolving both IOne >and ITwo.
If I do away with the ISystemConfigProviderInitialiser interface and lump the Initialize() into the ISystemConfigProvider and only LazyConstructAndRegisterSingleton the ISystemConfigProvider interface then all works fine as far as I can see but it then means that all consumers of ISystemConfigProvider can now see an Initialize() method that they shouldn't see.
I'd greatly appreciate some advice on this.
The problem here is that the Mvx IoC container treats the singleton aspect at the interface level, not the instantiated type. So it doesn't see that SystemConfigProvider is the same type and should only create one instance.
To work around this problem, there are a couple of options:
1) Simply instantiate the singleton at initialization time, then register that singleton for each interface:
var provider = Mvx.IocConstruct(SystemConfigProvider);
Mvx.RegisterSingleton<ISystemConfigProviderInitialiser>(provider);
Mvx.RegisterSingleton<ISystemConfigProvider>(provider);
2) Pass a builder Func to the registration
Mvx.RegisterSingleton(() =>
{
var provider = Mvx.IocConstruct<ISystemConfigProviderInitialiser>();
return provider;
});
Mvx.RegisterSingleton(() =>
{
var provider = Mvx.Resolve<ISystemConfigProviderInitialiser>();
if (provider == null)
{
throw new InvalidOperationException("ISystemConfigProviderInitialiser should be resolved first.");
}
return (ISystemConfigProvider)provider;
});
I'm assuming that the Initialiser should be resolved first, since there is an explicit Initialise() step, so I throw an exception if it is null.
I think Option #1 is probably better. It's simple and explicit.
Hope this helps.

Dependency injection and many implementations of interface

I have a small problem with using dependency injection in my project. To describe problem I will use simple example. Let's assume that I'm writing logger aplication and my end user is able to choose if log should be saved to file or written to the console. User control it by choosing checkboxes in running app. He can select both or only one. After selecting he clicks button "LOG" to perform action.
Now what I understand from my knowledge of DI I should create interfaces :
public interface ILogger
{
void log();
}
And two implementations
public class ConsoleLogger : ILogger
{
public void log()
{
...
}
}
public class FileLogger : ILogger
{
public void log()
{
...
}
}
I know that I can register both implementations in for example unity container and get them in constructor by using table but then I can't identify which implementations is FileLogger and which is ConsoleLogger (In case when user select only one checkbox)
Second options is use service locator pattern to resolve implementations from ioc by name. I dont know if it is a good approach
In my real application I will have more options than two and there will be a lot of shared interfaces by each option.
Maybe better is use MEF ?
Application will be written in WPF + PRISM.
The way I usually do this is to make your class depend on an ILoggerFactory, which can create ILogger instances given a name.
The factory implementation, LoggerFactory, would hold the container's kernel and be able to resolve the component by name.
Notice how the factory interface only tells you that it can create objects - it doesn't give you any hint about any underlying kernel, or DI framework - the factory implementation is the one that knows about those details.
Something like this:
public class MyLoggingClass
{
private readonly ILoggerFactory _loggerFactorty;
public MyLoggingClass(ILoggerFactory factory)
{
_loggerFactorty = factory;
var fileLogger = _loggerFactorty.Create("fileLogger");
var consoleLogger = _loggerFactorty.Create("consoleLogger");
}
}
public class LoggerFactory : ILoggerFactory
{
public ILogger Create(string key)
{
return kernel.Resolve<ILogger>(key);
}
}
Frameworks like Castle Windsor even give you these factories for free: you don't even have to write its implementation.
Service locator pattern is an anti-pattern now and should not be used.
In your case, it's better to use Strategy design pattern because you're creating objects dynamically at runtime.
The differences between dependency injection and strategy pattern are subtle but there are. For more information:
Strategy Pattern vs Dependency Injection
What is the difference between Strategy pattern and Dependency Injection?
To create objects dynamically, you could use factory method design pattern or abstract factory.
I don't see the point of creating a custom factory if all you want is basic IOC functionality. If you're going to develop the application using WPF and Prism, a good approach is to use one of the supported IOC containers. I have used Unity a lot and really like it. Another supported version is the MEF (as you suggested).
Both of them allow you to resolve interfaces using names. It is not bad practice and gives a structured way of resolving the correct interface.
For using Prism with Unity or Mef, see here:
https://learn.microsoft.com/en-us/previous-versions/msp-n-p/gg430868(v=pandp.40)

How do i handle static classes while using IOC

I just started migrating my web application to fully use Windsor IOC. Here is a little problem I am encountering;
I have couple of static classes which I used to store some application level global values
EG (Simplified version of the class):
public static class SiteInfo
{
public static Language Language = (Language)byte.Parse(SiteInfo.Val("language"));
public static string Code = Site.Code;
public static string Name = Site.Name;
public static SiteCachedData CachedData { get; set; }
public static Site Site { get; set; }
public static void Init()
{
//Get site info from DB here
//I need to inject _SiteRepository here but I can't
//since I don't have access to the constructor
}
}
I am new to IOC and I understand static classes are advised to be prevented. What is the good practice to handle this situation? I am thinking of converting this to a singleton but I am not sure if that is my best bet.
This is one of the reasons why I like to avoid static classes --they are hard to inject or invert control. They usually have to know intimate details of several low level classes. Since they are static classes you can leave them because they are already available to all of the other classes and don't require injection.
One trick that I've done is to create a second class that delegates into the static class. You can then put an interface onto the new class and get into an IoC framework easier.
public static class StaticClass
{
public static object Method()
}
public class NonstaticClass : INewInterface
{
public object Method()
{
return StaticClass.Method();
}
}
The good part of this refactor is that you can go method by method and then determine new objects and interfaces as you go. Eventually you may be able to get rid of the original static class. You would also register the new classes as singleton instances so that only one instance exists at a time.
In the context of an IoC container, it's a bit ambiguous to say 'convert it to a singleton'. If you mean the singleton design pattern, you probably shouldn't do it that way, as there are better alternatives in the IoC world.
IoC containers perform two main roles: to resolve dependencies between components, and to manage the lifetime of components. A container manages the lifetime of its components by deciding when to create and destroy component instances.
For example, when you call container.Resolve<SiteInfo>(), the container has to decide whether to re-use an existing SiteInfo instance or create a new one. How does the container decide? Well, when you register SiteInfo with the container, you can tell the container how you would like it to behave. If you register it as a Singleton, the container will only create a SiteInfo instance on the first call to container.Resolve<SiteInfo>(); on subsequent calls, it re-uses the existing SiteInfo instance.
The advantage of this technique over the singleton pattern is flexibility. If you use the design pattern, your SiteInfo class will forever be a singleton (unless you refactor). By using the container to manage the lifetime, you can change your mind later and just change the container registration code. Consumers of the component don't need to (and shouldn't) care whether the container provides them with a new instance or re-uses an existing one - they just call container.Resolve().
I'm not familiar with Windsor (I use Autofac), but it looks like you have two ways of registering a component as a singleton (I'm sure someone will correct me if this is wrong):
container.AddComponentLifeStyle<SiteInfo>(LifestyleType.Singleton)
or,
container.Register( Component.For<SiteInfo>()
.LifeStyle.Singleton );
However, a word of warning. In your example, your SiteInfo class has a dependency on the _SiteRepository class. You will therefore also need to register a _SiteRepository instance as a singleton in the container, so that it is available when the container resolves the SiteInfo. This _SiteRepository instance will remain in memory for the lifetime of the container, i.e. for the lifetime of the Web application, because it's a singleton. If the repository keeps a DB connection open, therefore, that connection will remain open for the same lifetime.
For this sort of reason, an alternative lifestyle is per-web-request - in other words, the container will create a new instance of your SiteInfo class once per web request. The per-web-request lifestyle is discussed in another question.
You can register an single instanec of a class in your container, so it behaves like a singleton. The container gives you the same instance every time.

Using the Ninject kernel as a Unit of Work object factory

So I'm starting to use Ninject for dependency injection and I'm wondering what people think of using a kernel as an object factory for Unit of Work type objects like Linq2Sql Datacontexts. I would just inject them like normal dependencies, but this introduces some object lifetime issues I'd like to avoid. DataContexts are different than general dependencies because you're supposed to spin up new instances as needed and dispose of them when you're done.
To do something like this I'd simply setup a provider like so...
class SomeDataContextProvider : Provider<SomeDataContext>
{
private static string _connectionString = "someConnectionString"
protected override SomeDataContext CreateInstance(IContext context)
{
return new SomeDataContext(_connectionString);
}
}
Bind them in a module...
class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<SomeDataContext>().ToProvider(SomeDataContextProvider);
}
}
And use the standard kernel when needed...
class MyClassThatNeedsADataContext
{
private StandardKernel _kernel = new StandardKernel(new MyModule());
public void SomeMethod()
{
using (var db = _kernel.Get<SomeDataContext>())
{
//Use the context
}
}
}
It seems a little heavy for what is essentially a static factory but I'm using Ninject for other stuff anyway. I like that it gives members on the team a convention for factories instead of just letting them wing it (creating a bunch of different factory classes in weird places, or just putting static methods on the objects etc).
Thoughts? Is there a better way to deal with Unit of work dependencies like DataContexts or WCF Service Clients using dependency injection?
I don't like injecting containers into classes since it creates a dependency between your application and the container, and makes it less clear what dependencies a class has. I don't really see how this approach gains you anything over a factory, so personally I'd create a 'DataContextFactory' and inject that into any classes that need to access the database.

Categories

Resources