StructureMap and objects not setup for DI/IoC - c#

I have a situation where I've created a factory method to create an object. However, the object has boilerplate code that needs execution before the object is created. Fixing that part of the design is out of scope for this question.
Also, when the object is created, a status display is updated on screen. This requires that this status display be instantiated before and be visible and the application be in a running state before creating this object. It is passed to the factory as a dependency.
I'm using v3.1.4.143 of StructureMap.
So, here's what I'd be doing in the normal world (pre-IoC):
GraphicsInterface GetGraphics()
{
VideoDevicesList.GetVideoDevices();
// Some logic here to determine the device to use...
// Also, a status display is being updated to inform the user of
// what's happening at this point.
VideoDevice device = ...;
// The second parameter is a constant value, but the first is not.
return new GraphicsInterface(device, featureLevels.FL5);
}
Seems simple enough, but ideally I'd like to be able to pass that graphics object around via injection as it'll be needed in many spots.
So, in structure map, I created a factory function to do the above. However it's giving me grief.
new Container(obj =>
{
// This is passed to the object that depends on it.
// I've just left it out for brevity.
// It'd go something like: _graphics = _getGraphicsFactory();
// where _getGraphicsFactory is the factory function below.
For<Func<IStatusDisplay, GraphicsInterface>>
.Use<Func<IStatusDisplay, GraphicsInterface>>(GetGraphics);
}
Only this gives me an error about GraphicsInterface not being registered. That's fine, I should be able to register the GraphicsInterface object. Except that I can't register GraphicsInterface because the constructor requires two parameters, one of which must be queried before creating the object and can only be set up via the GetVideoDevices method above and it seems StructureMap tries to create the object for me when I call _getGraphicsFactory() (which is weird, I would have it expected it to execute my function to create the object).
I tried even calling GetInstance like this inside of my GetVideoDevices method:
_container
.With<VideoDevice>(device)
.With<FeatureLevel>(FeatureLevel.FL5)
.GetInstance<Graphics>();
But no dice...
So, does anyone have an idea on how I'd get this to work?

Whenever you are scratching your head trying to work out how to create instances at runtime, you need to step back and look for a design pattern that will fit the problem. DI is meant for composing applications, but controlling runtime behavior should be part of the application design - that is, the part that runs after the application is composed.
In this particular case, Abstract Factory would be a good fit. It allows you to separate the composed services (those injected through the constructor) from runtime services (those passed as method parameters).
However, you should restrict a factory to doing exactly one thing - creating the runtime instance. All other work should be part of other services. This gives you a clean way to inject a runtime object into your service and still allow the service behavior to be tested independently of this step.
public interface IGraphicsFactory
{
GraphicsInterface Create(VideoDevice device);
void Release(GraphicsInterface graphicsInterface);
}
public class GraphicsFactory : IGraphicsFactory
{
private readonly FeatureLevel featureLevel;
// Parameters injected are done so by the DI container
public GraphicsFactory(FeatureLevel featureLevel)
{
this.featureLevel = featureLevel;
}
// Parameters passed are part of the application runtime state
public GraphicsInterface Create(VideoDevice device)
{
return new GraphicsInterface(device, this.featureLevel);
}
// Method for releasing disposable dependencies (if any)
public void Release(GraphicsInterface graphicsInterface)
{
var disposable = graphicsInterface as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
Your factory can then be supplied to a service during application composition, and runtime instances of GraphicsInterface can be created at runtime. As per your requirement, this can easily be done in multiple spots by injecting it into the constructors of multiple services.
public class SomeService : ISomeService
{
private readonly IGraphicsFactory graphicsFactory;
public SomeService(IGraphicsFactory graphicsFactory)
{
if (graphicsFactory == null)
throw new ArgumentNullException("graphicsFactory")
this.graphicsFactory = graphicsFactory;
}
public void DoSomething()
{
// Get video device here. It will likely be best to
// delegate that to another specialized service
// that is injected into this class.
VideoDevice device = ...;
var graphics = this.graphicsFactory.Create(device);
try
{
// Do something with graphics
}
finally
{
this.graphicsFactory.Release(graphics);
}
}
}
As for selecting the device to use, that could either be done with another Abstract Factory, or if it is something that is done often, you could use a Strategy Pattern to load all of the options at composition time, and then selectively choose the device at runtime. Or, if your devices are disposable, you could make a Strategy of Abstract Factories or look to some more advanced design pattern to clean them up.
You might also consider using an adapter pattern to create an abstraction for GraphicsInterface if it doesn't already have a suitable that can be injected (and swapped) that has all of the members you are after.
public interface IGraphicsInterfaceAdapter
{
// Extract all public properties of GraphicsInteface and define them here.
}
public class GraphicsInterfaceAdapter : IGraphicsInterfaceAdapter
{
public GraphicsInterfaceAdapter(VideoDevice device, FeatureLevel featureLevel)
: base(device, featureLevel)
{
}
}

Related

Register one of many types to an interface using Autofac

Autofac has a TON of registration techniques, most of which I have trouble understanding. Reading through the docs for a while, I didn't see anything that would allow me to do this.
I have a system outside of my control that, based on some command line parameters, instantiates a certain class. This class is one of many that all derive from a common base class. For example:
abstract class BaseCommand {}
class CommandOne : BaseCommand {}
class CommandTwo : BaseCommand {}
I won't know until after component registration which derived class (either CommandOne or CommandTwo) will be constructed by this library. Here's a rough outline of what the code looks like:
static void Main() {
// Do all the autofac registrations
IContainer container = CompositionRoot.Setup();
// Parse command line arguments
ParseCommandLine(type => container.Resolve(type))
}
The ParseCommandLine() method is the "black box" code that constructs either of the two classes I mentioned before. It does so by invoking the lambda I pass to it. It will never instantiate both classes, but only one of them.
What I need is for Autofac to allow me to "lazy register" BaseCommand as a service. That is to say, at registration time, we don't know which specific context will be chosen but we know it will always be derived from BaseCommand. So something roughly like this:
var builder = new ContainerBuilder();
builder.Register(ctx => /*Access the type passed to Resolve() and instantiate that*/).As<BaseCommand>().AsSelf().SingleInstance();
So essentially what I want is:
We can only ever have 1 concrete type registered for BaseCommand
We don't know what that implementation is until resolve happens
We use the type provided to Resolve() to decide
We will only ever have a single instance of that type.
An attempt to resolve any other concrete type should fail (for example, once I resolve type CommandOne, resolving CommandTwo should throw an exception)
How can I accomplish this in Autofac?
I'm not sure you're going to be able to get 100% of what you want, but I think you can get pretty close with a bit of indirection.
First, you'll need a sort of mediator thing that can be used in lambda expressions so you can delay the actual registration contents. It has a few jobs:
Store the selected type that the black box picks. This way it can be used in the lambda to "defer" figuring out which of the commands were selected.
Register the available commands, but with a random "key" so they don't accidentally get resolved. The container is immutable so you can't "unregister" things later, and anything you need to resolve (or potentially resolve) needs to be registered.
Resolve the available command, but using a filter so you get the selected one.
It'll look something like this:
public static class CommandFilter
{
private static readonly Guid _id = Guid.NewGuid();
public static Type SelectedCommand { get; set; }
public static void Register(ContainerBuilder builder, Type type)
{
// The "secret key" will be required to resolve these,
// so container.Resolve<T>() won't work - it'd have
// to be container.ResolveKeyed<T>(_id) to get it.
builder.RegisterType(type).Keyed(type, _id);
}
public static BaseCommand Resolve(IComponentContext context)
{
// Only resolve the selected implementation, everything else
// stays "hidden."
return context.ResolveKeyed(_id, CommandFilter.SelectedCommand) as BaseCommand;
}
}
Now you need to register all the BaseCommand implementations but using this filter thing. That means some manual assembly scanning for you.
// WARNING: I can never remember the right direction for
// IsAssignableFrom so check this by testing.
var asm = typeof(BaseCommand).Assembly;
foreach(var type in asm.GetTypes().Where(t => typeof(BaseCommand).IsAssignableFrom(t)))
{
// Register your "secret" keyed registrations.
CommandFilter.Register(builder, type);
}
// Register the BaseCommand itself.
builder.Register(ctx => CommandFilter.Resolve(ctx))
.As<BaseCommand>()
.SingleInstance();
In your black box, the key will be to FIRST set the filter type, THEN resolve.
ParseCommandLine(type => {
CommandFilter.SelectedCommand = type;
container.Resolve<BaseCommand>();
});
The lambda in the registration allows you to defer selection; the lambda passed to ParseCommandLine can take the selection; and only the one you want will be resolved. Everything else is registered but effectively inaccessible, and carte blanche calls to container.Resolve<NotTheSelectedCommand>() will fail with a resolution exception because they're registered as keyed and will require the key to resolve.
I haven't actually run this through a compiler, but it seems like this should do the trick. Depending on the "real" system, you may need to put a lock around where the SelectedCommand gets set because, while container.Resolve<T>() is thread-safe, you've got that selection mechanism running outside it. Might also need some error handling for folks trying to resolve from the command filter before SelectedCommand is set, that sort of thing.

Why using the factory pattern when a simple dependecy injection is enough

Im looking to this example to understand the use of factory pattern.
I'm really amator in this field so excuse my silly question.
My problem is that i don't see the use of the factory pattern which return us the interface that we can inject it directly when we need to use it.
In the example above I would do something like this:
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategy _shippingStrategy;
public Program(IShippingStrategy shippingStrategy)
{
_shippingStrategy= shippingStrategy;
}
public int DoTheWork(Order order)
{
// assign properties just as an example
order.ShippingMethod = "Fedex";
order.OrderTotal = 90;
order.OrderWeight = 12;
order.OrderZipCode = 98109;
int shippingCost = _shippingStrategy.CalculateShippingCost(order);
return shippingCost;
}
}
Instead of injecting the factory :
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategyFactory _shippingStrategyFactory;
public Program(IShippingStrategyFactory shippingStrategyFactory)
{
_shippingStrategyFactory = shippingStrategyFactory;
}
public int DoTheWork(Order order)
{
// assign properties just as an example
order.ShippingMethod = "Fedex";
order.OrderTotal = 90;
order.OrderWeight = 12;
order.OrderZipCode = 98109;
IShippingStrategy shippingStrategy = _shippingStrategyFactory.GetShippingStrategy(order);
int shippingCost = shippingStrategy.CalculateShippingCost(order);
return shippingCost;
}
}
Why taking the bruden to create a factory (thus adding an extra layer) when we can inject the interface directly to wherever we need to use it ?
I think you don't want just another article about the factory pattern but a short comprehensive answer.
So, I'd like to focus on two things.
More flexibility
Most commonly, you'd set up your composition root where you basically say ...
"if anyone wants IAnyService, he should get MyAnyServiceImplementation".
This is fixed for your application. Once set up, your dependency injection container will serve the class instances you registered but you should not try to re-configure that container again. That's perfect for startup flexibility like registering implementation for data access components by the application's configuration, for example. Say ...
"if anyone wants IUserRepository, he should get MsSqlUserRepository because we are working with MSSQL server".
Of course, having that "immutable" composition root limits the possibilities to choose an implementation in runtime depending of the applications' state.
Instead you can inject a class which decides on a current state which service implementation to choose. Data validation is a typical scenario for that pattern because there might be different rules for different entities on your system. The buzzword here is "rule pattern" or "strategy pattern".
Lifetime control
Think of a long-living class instance like a view (user interface) or any class attached to it (like a viewmodel or a controller). As long as a user is active on a view, the class is alive. By injecting a class instance to the constructor of the view controller, for example, you hold an active instance of it as long as the view lives.
Let's say you want to use a data repository to connect to a database for example. These database access calls should be short and you do not want to keep connections open for a long time. With a repository factory, you could control the lifetime very precisely and make sure that the class is removed after it has been used:
using (var repository = new _factory.CreateRepository(...))
{
return repository.GetAnything();
}
With this, a very lightweight class - the factory - gets injected and lives as long as the view controller lives. The heavy classes - the connection things - should not live long and are just created when needed.
In fact, chances are that the repository is not instantiated at all if there's no requirement to load the data (because of an upfront cache hit, for example). If you would have injected the repository directly, you'd guarantee that one long living instance lives in memory in every case.
If you check the code for the factory you can see that depending on the ShippingMethod of the order a different implementation of the IShippingStrategy is returned by the factory. Since the ShippingMethod is only known once DoTheWork has been called it's impossible to inject the right implementation when the class is constructed (and the same class might even need different implementations for different orders).

Register, Resolve, Release pattern usage

I'm currently reading the book Dependency Injection in .NET by Mark Seeman. In this book he recommends the Register, Resolve, Release pattern and also recommends that each of these operations should appear only once in your application's code.
My situation is the following: I'm creating an application that communicates with a PLC (a kind of industrial embedded computer) using a proprietary communication protocol for which the PLC manufacturer provides an library. The library's documentation recommends creating a connection to the PLC and maintaining it open; then using a timer or a while loop, a request should be periodically sent to read the contents of the PLC's memory, which changes over time.
The values read from the PLC's memory should be used to operate on a database, for which I intend to use Entity Framework. As I understand it, the best option is to create a new dbContext on every execution of the loop in order to avoid a stall cache or concurrency problems (the loop could be potentially executing every few milliseconds for a long time while the connection is kept open all the time).
My first option was calling Resolve on application construction to create a long-lived object that would be injected with the PLC communication object and would handle loop execution and keep the connection alive. Then, at the beginning of every loop execution I intended to call Resolve again to create a short-lived object that would be injected with a new dbContext and which would perform the operations on the database. However, after reading the advice on that book I'm doubting whether I'm on the right track.
My first idea was to pass a delegate to the long-lived object upon its construction that would allow it to build new instances of the short-lived object (I believe it is the factory pattern), thus removing the dependency on the DI container from my long-lived object. However, this construct still violates the aforementioned pattern.
Which is the right way of handling Dependency Injection in this situation?
My first attempt without DI:
class NaiveAttempt
{
private PlcCommunicationObject plcCommunicationObject;
private Timer repeatedExecutionTimer;
public NaiveAttempt()
{
plcCommunicationObject = new PlcCommunicationObject("192.168.0.10");
plcCommunicationObject.Connect();
repeatedExecutionTimer = new Timer(100); //Read values from PLC every 100ms
repeatedExecutionTimer.Elapsed += (_, __) =>
{
var memoryContents = plcCommunicationObject.ReadMemoryContents();
using (var ctx = new DbContext())
{
// Operate upon database
ctx.SaveChanges();
}
}
}
}
Second attempt using Poor man's DI.
class OneLoopObject
{
private PlcCommunicationObject plcCommunicationObject;
private Func<DbContext> dbContextFactory;
public OneLoopObject(PlcCommunicationObject plcCommunicationObject, DbContext dbContext
{
this.plcCommunicationObject = plcCommunicationObject;
this.dbContext = dbContext;
}
public void Execute()
{
var memoryContents = plcCommunicationObject.ReadMemoryContents();
// Operate upon database
}
}
class LongLivedObject
{
private PlcCommunicationObject plcCommunicationObject;
private Timer repeatedExecutionTimer;
private Func<OneLoopObject> oneLoopObjectFactory;
public LongLivedObject(PlcCommunicationObject plcCommunicationObject, Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory)
{
this.plcCommunicationObject = plcCommunicationObject;
this.dbContextFactory = dbContextFactory;
this repeatedExecutionTimer = new Timer(100);
this.repeatedExecutionTimer.Elapsed += (_, __) =>
{
var loopObject = oneLoopObjectFactory(plcCommunicationObject);
loopObject.Execute();
}
}
}
static class Program
{
static void Main()
{
Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory = plc => new OneLoopObject(plc, new DbContext());
var myObject = LongLivedObject(new PlcCommunicationObject("192.168.1.1"), oneLoopObjectFactory)
Console.ReadLine();
}
}
The first edition states (chapter 3, page 82):
In its pure form, the Register Resolve Release pattern states that you should only make a single method call in each phase [...] an application should only contain a single call to the Resolve method.
This description stems from the idea that your application only contains either one root object (typically when writing a simple console application), or one single logical group of root types, e.g. MVC controllers. With MVC controllers, for instance, you would have a custom Controller Factory, which is provided by the MVC framework with a controller type to build. That factory will, in that case, only have a single call to Resolve while supplying the type.
There are cases, however, where your application has multiple groups of root types. For instance, a web application could have a mix of API Controllers, MVC Controllers and View Components. For each logical group you would likely have a single call to Resolve, and thus multiple calls to Resolve (typically because each root type gets its own factory) in your application.
There are other valid reasons for calling back into the container. For instance, you might want to defer building part of the object graph, to combat the issue of Captive Dependencies. This seems your case. Another reason for having an extra resolve is when you use the Mediator pattern to dispatch messages to a certain implementation (or implementations) that can handle that message. In that case your Mediator implementation would typically wrap the container and call Resolve. The Mediator’s abstraction would likely be defined in your Domain library, while the Mediator’s implementation, with its knowledge of the container, should be defined inside the Composition Root.
The advice of having a single call to Resolve should, therefore, not be taken literally. The actual goal here is to build a single object graph as much as possible in one call, compared to letting classes themselves call back into the container to resolve their dependencies (i.e. the Service Locator anti-pattern).
The other important point that (the second edition of) the book makes is
Querying for Dependencies, even if through a DI Container, becomes a Service Locator if used incorrectly. When application code (as opposed to infrastructure code) actively queries a service in order to be provided with required Dependencies, then it has become a Service Locator.
A DI Container encapsulated in a Composition Root isn't a Service Locator—it's an infrastructure component.
(note: this quote is from the second edition; Although the first edition contains this information as well, it might be formulated differently).
So the goal of the RRR pattern is to promote encapsulation of the DI Container within the Composition Root, which is why it insists in having a single call to Resolve.
Do note that while writing the second edition, Mark and I wanted to rewrite the discussion of the RRR pattern. Main reason for this was that we found the text to be confusing (as your question indicates). However, we eventually ran out of time so we decided to simply remove that elaborate discussion. We felt that the most important points were already made.
Combining factories with DI is a common solution. There is absolutely nothing wrong with creating and disposing objects dynamically in your program (it's much more difficult and limiting to try to account for every bit of memory you'll need up front).
I found a post by Mark Seeman about the Register, Resolve, Release Pattern (RRR) here: http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/
He states that...
The names originate with Castle Windsor terminology, where we:
Register components with the container
Resolve root components
Release components from the container
So the RRR pattern is limited to the DI Container. You do indeed Register and Release components with the container one time in your application. This says nothing about objects not injected through DI, ie those objects created dynamically in the normal execution of your program.
I have seen various articles use distinct terminology for the two different types of things you create in your program with relation to DI. There are Service Objects, ie those global objects injected via DI to your application. Then there are Data or Value Objects. These are created by your program dynamically as needed and are generally limited to some local scope. Both are perfectly valid.
It sounds like you want to be able to both resolve objects from the container and then release them, all without directly referencing the container.
You can do that by having both a Create and a Release method in your factory interface.
public interface IFooFactory
{
Foo Create();
void Release(Foo created);
}
This allows you to hide references to the container within the implementation of IFooFactory.
You can create your own factory implementation, but for convenience some containers, like Windsor, will create the factory implementation for you.
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<Foo>());
container.Register(
Component.For<IFooFactory>()
.AsFactory()
);
You can inject the factory, call Create to obtain an instance of whatever the factory creates, and when you're done with it, pass that instance to the Release method.
Windsor does this by convention. The method names don't matter. If you call a method of the interface that returns something, it attempts to resolve it. If a method returns void and takes an argument then it tries to release the argument from the container.
Behind the scenes it's roughly the same as if you wrote this:
public class WindsorFooFactory : IFooFactory
{
private readonly IWindsorContainer _container;
public WindsorFooFactory(IWindsorContainer container)
{
_container = container;
}
public Foo Create()
{
return _container.Resolve<Foo>();
}
public void Release(Foo created)
{
_container.Release(created);
}
}
The factory implementation "knows" about the container, but that's okay. Its job is to create objects. The factory interface doesn't mention the container, so classes that depend on the interface aren't coupled to the container. You could create an entirely different implementation of the factory that doesn't use a container. If the object didn't need to be released you could have a Release method that does nothing.
So, in a nutshell, the factory interface is what enables you to follow the resolve/release part of the pattern without directly depending on the container.
Here's another example that shows a little bit more of what you can do with these abstract factories.
Autofac uses Func<> as the factory pattern so you could always do the same:
public class Foo()
{
private readonly Func<Bar> _barFactory;
public Foo(Func<Bar> barFactory)
{
_barFactory = barFactory;
}
}
Adding Factory Interfaces for factories is not something I think anyone should need to do most of the time, it's extra work for little to no reward.
Then you simply need to keep track of which entities are externally owned or DI owned for your release (Dispose in C#).

Can I use Ninject to instantiate singleton services that nothing depends on?

I have some services in my asp.net mvc application that listen for AMQP messages and invoke methods.
No controllers depend on this, so it won't get instantiated on its own.
I could instantiate it manually, explicitly providing its dependencies with kernel.Get but it feels like I shouldn't have to do that.
Can I make Ninject instantiate classes in singleton scope eagerly even when nothing else depends on it?
You cannot have ninject instantiate stuff in case you don't ask it to instantiate something yourself.
The simple way is to ask ninject to instantiate things at composition root:
var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies()); // loads all modules in assemlby
//...
// resolution root completely configured
kernel.Resolve<IFooSingleton>();
kernel.Resolve<IBarSIngleton>();
There is one alternative, actually, which is not the same, but can be used to achieve a similar effect. It requires that there is at least one single other service instantiated soon enough: Ninject.Extensions.DependencyCreation.
It works like this:
kernel.Bind<string>().ToConstant("hello");
kernel.Bind<ISingletonDependency>().To<SingletonDependency>()
.InSingletonScope();
kernel.DefineDependency<string, ISingletonDependency>();
kernel.Get<string>();
// when asking for a string for the first time
// ISingletonDependency will be instantiated.
// of course you can use any other type instead of string
Why
Ninject is unlike some other containers (for example Autofac) not "built" in stages. There's no concept of first creating the bindings, and then creating the kernel to use them. The following is perfectly legal:
kernel.Bind<IFoo>()...
kernel.Get<IFoo>()...
kernel.Bind<IBar>()...
kernel.Get<IBar>()...
so ninject can't possibly know when you want the singletons to be instantiated. With autofac it's clear and easy:
var containerBuilder = new ContainerBuilder();
containerBuilder
.RegisterType<Foo>()
.AutoActivate();
var container = containerBuilder.Build(); // now
Coming from Guice in Java, I've sorely missed the pattern of eager singletons. They are useful in scenarios where for example modules act as plugins. If you imagine that a service is assembled from modules that are specified in a configuration, you could see a problem of then also trying to specify what this module needs to be auto-instantiated when the application is started.
For me the module is where the composition of the application is defined and separating eager singletons into another place in the code feels more clunky and less intuitive.
Anyway, I've been able to very easily implement this as a layer on top of Ninject, here's the code:
public static class EagerSingleton
{
public static IBindingNamedWithOrOnSyntax<T> AsEagerSingleton<T>(this IBindingInSyntax<T> binding)
{
var r = binding.InSingletonScope();
binding.Kernel.Bind<IEagerSingleton>().To<EagerSingleton<T>>().InSingletonScope();
return r;
}
}
public interface IEagerSingleton { }
public class EagerSingleton<TComponent> : IEagerSingleton
{
public EagerSingleton(TComponent component)
{
// do nothing. DI created the component for this constructor.
}
}
public class EagerSingletonSvc
{
public EagerSingletonSvc(IEagerSingleton[] singletons)
{
// do nothing. DI created all the singletons for this constructor.
}
}
After you've created your kernel, add a single line:
kernel.Get<EagerSingletonSvc>(); // activate all eager singletons
You use it in a module like this:
Bind<UnhandledExceptionHandlerSvc>().ToSelf().AsEagerSingleton();

Is this basically what an IOC like NInject does?

Normally I would do this:
public class DBFactory
{
public UserDAO GetUserDao()
{
return new UserDao();
}
}
Where UserDao being the concrete implementation of IUserDao.
So now my code will be littered with:
DBFactory factory = new DBFactory();
IUserDao userDao = factory.GetUserDao();
User user = userDao.GetById(1);
Now if I wanted to swap implementaitons, I would have to go to my DBFactory and change my code to call a different implementation.
Now if I used NINject, I would bind the specific implementation on application startup, or via a config file. (or bind based on specific parameters etc. etc.).
Is that all there is too it? Or is there more?
(reason I am asking if I want to know how it will help me here: Help designing a order manager class)
In a word, yes. Your code would then change in structure, so your dependencies would be passed in via the constructor (or setters, which I am personally not a fan of). You would no longer say "new XXX()" for services in the body of your methods.
You also would not likely need the factory anymore at all, since the DI framework can act as a factory. You would likely just need a constructor dependency on IUserDAO.
So something like:
public class ClassThatNeedsUserDAO
{
private readonly IUserDAO _userDAO;
public ClassThatNeedsUserDAO(IUserDAO userDAO)
{
_userDAO = userDAO;
}
public User MyMethod(userId)
{
return _userDAO.GetById(int userId);
}
}
There is more to it, one example would be if the constructor of UserDao required some other objects to be passed as arguments (dependencies).
You could have ninject automatically create and inject those objects, saving some lines of code but more importantly ensuring that every class is loosely coupled with its dependencies.

Categories