I'm trying to implement DI in a class, but I'm not sure that my design is appropriate.
The relevent code in the class I want to add DI to
class DoerValidation
{
public DoerValidation()
{
compileData();
}
private void compileData()
{
doersActive = Doer.GetActiveDoers();
//...
}
}
And in my Doer class
public partial class Doer
{
private static readonly DoerRepository repository = new DoerRepository();
public static IEnumerable<Doer> GetActiveDoers()
{
return repository.Doers.Where(c => c.Person.IsActive);
}
}
I just don't get how I could implement DI in this situation. Maybe the GetActiveDoers method is bad design? Where would you put this method otherwise?
Would it be a good practice to start adding new methods directly in the repository? Some people told me it should stay clean so it implements only this
public interface IDoerRepository
{
IQueryable<Doer> Doers { get; }
void SaveDoer(Doer doer);
void DeleteDoer(Doer doer);
}
It sounds like you need to inject the DoerRepository into DoerValidation basically - pass it into the constructor.
Both the GetActiveDoers and the static variable go against the principles of DI, IMO.
Static methods and properties are procedural in nature. If you expose your GetActiveDoers() method statically, there is no way to inject its functionality -- clients can only ignore it or use it inline wherever it's needed.
If you're committed to DI and to a static implementation, you need to write an instance wrapper for that static class and inject the instance wrapper.
Related
If I want to have a service which creates multiple objects which have injectable dependencies how do I code that?
public class MyCreator : ICreator
{
private readonly IAdapter _adapter;
public MyCreator()
{
_adapter = adapter;
}
public List<MappedObjects> Map()
{
List<MappedObjects> mo = new List<MappedObjects>();
foreach (ObjectToMap otm in ObjectToMap)
{
mo.Add(new MappedObject(otm, InjectedDependency dep));
}
}
}
If I register MyCreator with DI, will it know how to provide InjectedDependency?
EDIT: InjectedDependency is not one instance which should be passed to each MappedObject. I want a new instance of InjectedDependency for each new MappedObject.
Perhaps that means I have to create some kind of Factory object which know's how to create instances of InjectedDependency. I cannot provide more code because I don't know how to articulate what I need in C#.
I'm using teh inbuilt DI with .NET Core 2.2.
You will indeed need a factory:
public class MyCreator : ICreator
{
private readonly IInjectedDependencyFactory _factory;
public MyCreator(IInjectedDependencyFactory factory)
{
_factory = factory;
}
public List<MappedObjects> Map()
{
return ObjectToMap.Select(otm => new MappedObject(otm, _factory.Create())).ToList();
}
}
Obviously, you will have to write the factory class and interface and register them with your DI container.
You could also inject the DI container itself, IServiceProvider to get your new services directly from the container, given that that already is a factory. However, many people might consider this a code smell and the Service Locator pattern (that's what it would be) is not held in high regard nowadays. Other people might consider it wasteful to implement a factory on top of a factory. I guess there is no right way, you will have to live with some people calling it wrong, no matter what you do.
To keep your code testable, you need to inject the implementation of InjectedDependency in your MyCreator constructor.
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).
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 =)
I'd like to instantiate a class when I start the application and then use that object in every class (custom ValidationAttributes, controllers, etc).
Where should I instantiate that class to have access to it everywhere?
I'm using ASP.NET MVC with C#.
Besides the choices already given, you can use dependency injector to control the management and lifetime of expensive objects. Castle Windsor, Ninject and StructureMap play well with asp.net mvc.
You could make it a static property of the MvcApplication class (global.asax), and instantiate it in Application_Start.
I place such object instances in the HttpRuntime Cache.
public static MyCacheHelper
{
public static MyType GetMyInstance
{
get
{
if (HttpRuntime.Cache[MY_CACHE_KEY] == null)
{
HttpRuntime.Cache[MY_CACHE_KEY] = new MyType();
}
return (MyType)HttpRuntime.Cache[MY_CACHE_KEY];
}
}
}
It sounds like you are wanting to create a Singleton class. This article has many examples of how to achieve this, and their caveats. From the article, this is probably the simplest way to create a singleton:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Anywhere in your code you need to access your class, you would write Singleton.Instance.MyMethod() (following the above example), much like you access string.IsNullOrEmpty(). Aside of the boiler plate code included above, you can code your properties and methods as you would any other class.
Suppose that your code is properly designed for DI and IOC through constructor injection of any dependencies. Then whether an IOC container or DI-by-hand is used or not at the composition root doesn't matter much for this problem. I think.
Anyway, I find myself over and over again in a mental struggle with how I should best deal with scope-based services, like transactions or other obviously transient operations. There are constraints that I want to abide to:
Don't let dependency interfaces be IDisposable - it's a leaky abstraction that only the actual implementing type (and the fiddler sitting at the composition root) should care about.
Don't use static service locator types deep down the graph to resolve a dependency - only inject and resolve through the constructor.
Don't pass the IOC container, if any, as a dependency down the graph.
To be able to use using, we need IDisposable, but since a dependency interface shouldn't be IDisposable, how do you get around it to get scoped behavior?
In cases like this I would inject a service factory that creates those scoped services and let the service interface derive from IDisposable. This way the factory would be responsible to create the appropriate service instances and the only point that decides which service implementation to return. You would not need to inject the scoped service anywhere.
public interface ITransaction : IDisposable
{
}
public interface ITransactionFactory
{
ITransaction CreateTransaction();
}
public class Foo
{
private readonly ITransactionFactory transactionFactory;
public Foo(ITransactionFactory transactionFactory)
{
this.transactionFactory = transactionFactory;
}
public void DoSomethingWithinTransaction()
{
using(ITransaction transaction = this.transactionFactory.CreateTransaction())
{
DoSomething();
}
}
}
Most IoC containers today have substantial built-in support for units of work of this nature.
In Autofac, the mechanism that best fits your requirements is the Owned<T> relationship type. You can see it in action (and get some more material) via this article.
Hope this helps,
Nick
Roll your own "garbage collector" maybe? Something that periodically checks IsComplete and/or an LastAccessed attribute of a Dictionary<Transaction> and wastes the "old" ones. It's "a walking memory leak" but either you clean-up explicitly (like through IDisposable) or you workout how to clean-up automatically.
There may be an AOP solution to kicking-off the "gc"... a commit/rollback sounds like a good place to cut... and maybe you won't even need a GC at all... just cleanup the transaction on the way back-up the callstack from commit or rollback.
Good luck with it. I'll be interested to see what solutions (and ideas) other people come-up with.
Cheers. Keith.
I guess another alternative you could use is to wrap your instances with a disposable type, that way it could automatically handle the disposal of the type regardless of whether the type is actually disposable. E.g, I could define something like:
public class DisposableWrapper<T> : IDisposable
{
private readonly T _instance;
private readonly IDisposable _disposable;
public DisposableWrapper(T instance)
{
_instance = instance;
_disposable = instance as IDisposable;
}
public void Dispose()
{
if (_disposable != null)
_disposable.Dispose();
}
public static implicit operator T(DisposableWrapper<T> disposableWrapper)
{
return disposableWrapper._instance;
}
}
(Hopefully with a bit more error handling!)
Given that I know at the point of disposal whether the type is disposable, I can call it accordingly. I can also provide an implicit operator to cast back to the inner type from it. With the above, and a nifty extension method:
public static class DisposableExtensions
{
public static DisposableWrapper<T> Wrap<T>(this T instance)
{
return new DisposableWrapper<T>(instance);
}
}
Let's imagine that I have a service I am injecting into a type, it could be:
public interface IUserService
{
IUser GetUser();
}
I could potentially do something like:
public HomeController(IUserService service)
{
using (var disposable = service.Wrap())
{
var user = service.GetUser();
// I can even grab it again, implicitly.
IUserService service2 = disposable;
}
}
Now regardless of whether that concrete implementation of IUserService is disposable or not, I can still safely work on the assumption that it doesn't matter.
Another quick console example:
class Program
{
static void Main(string[] args)
{
using (var instance = new ClassA().Wrap())
{
ClassA instanceA = instance;
}
using (var instance = new ClassB().Wrap())
{
ClassB instanceB = instance;
}
Console.ReadKey();
}
}
public class ClassA
{
}
public class ClassB : IDisposable
{
public void Dispose()
{
Console.Write("Disposed");
}
}