Providing that I have a class as follows
public class Foo
{
public Foo(string someTitle, IFooService fooService)
{
// do stuff
}
}
I know that I can instantiate it like this using DI and autofac
public class Bar
{
public Bar(Func < string, IFooService, Foo > foo, IFooService fooService)
{
var foo = foo("some string", fooService);
}
}
but I'm wondering if there's any way for Bar to not have to know anything about IFooService? I'd like to not have to inject IFooService into Bar just to satisfy the func.
Essentially something like this
// pseudo code - don't use
public class Bar
{
public Bar(Func < string, Foo > foo)
{
var foo = foo("some string");
}
}
What I'm really trying to do in my app is remove all instances of Service Location, and rely solely on Dependency Injection.
Autofac should be able to do exactly what you want by using the Func<T> implicit relationship.
Here is a small repro showing how you can omit the IFooService parameter in the Func<T> and as long as the other dependencies can be resolved by Autofac, you're good to go.
Sample types that do some crazy work...
public class Bar
{
private Foo _foo;
// This constructor looks like what you're aiming for...
public Bar(Func<string, Foo> factory)
{
this._foo = factory("title");
}
public void ShowMeCoolStuff()
{
this._foo.DoWork();
}
}
public class Foo
{
private string _title;
private IFooService _service;
// The Foo class takes the title AND an IFooService...
public Foo(string title, IFooService service)
{
this._title = title;
this._service = service;
}
public void DoWork()
{
Console.WriteLine("Foo title = {0}", this._title);
this._service.DoMoreWork();
}
}
public interface IFooService
{
void DoMoreWork();
}
public class FooService : IFooService
{
public void DoMoreWork()
{
Console.WriteLine("FooService doing more work.");
}
}
When you register, make sure all the dependencies are registered - Foo, Bar, something implementing IFooService:
var builder = new ContainerBuilder();
builder.RegisterType<Foo>();
builder.RegisterType<Bar>();
builder.RegisterType<FooService>().As<IFooService>();
var container = builder.Build();
When you resolve, everything chains down the line. This resolution...
var bar = container.Resolve<Bar>();
bar.ShowMeCoolStuff();
...will yield the following console output:
Foo title = title
FooService doing more work.
There is fairly robust documentation with examples over on the Autofac site.
That's where you use factories for:
public interface IFooFactory
{
Foo CreateFoo(string value);
}
And bar can simply depend on IFooFactory.
The implementation can look as follows:
public class FooFactory : IFooFactory
{
private readonly IFooService fooService;
public FooFactory(IFooService fooService)
{
this.fooService = fooService;
}
public Foo CreateFoo(string value)
{
return new Foo(value, this.fooService);
}
}
But the given string seems like a runtime value, i.e. a value that changes from request to request or from call to call. Prevent mixing runtime values with design time dependencies as explained here, here and here. Instead, pass the runtime value as method argument to the Foo methods you are calling. That will completely remove the problem.
Related
I'm trying to create an generic service-interface per logic-class to communicate with the database.
See code examples for an explanation better than words.
For example:
Foo
public interface ICreateFoo
{
void CreateFoo(Foo foo);
}
public interface IReadFoo
{
void ReadFoo(Foo foo);
}
Bar
public interface ICreateBar
{
void CreateBar(Bar bar);
}
public interface IReadBar
{
void ReadBar(Bar bar);
}
IFooService
public interface IFooService : ICreateFoo, IReadFoo, IReadBar
{ }
FooService instance
public class FooService : ICreateFoo, IReadFoo
{
public void CreateFoo(Foo foo){
//Something
}
public void ReadFoo(Foo foo){
//Something
}
}
BarService instance
public class BarService : ICreateBar, IReadBar
{
public void CreateBar(Bar bar){
//Something
}
public void ReadBar(Bar bar){
//Something
}
}
FooLogic instance
public class FooLogic : IFooService
{
private readonly IFooService _fooService;
public FooLogic(IFooService fooService) {
_fooService = fooService;
}
public void CreateFoo(Foo foo){
//Check if bar exists
if(_fooService.ReadBar())
_fooService.AddFoo(foo);
else
//nothing
}
}
But the dependency injection ofcourse doesn't know which service class instance it should get, is this a bad usage of interfaces? Because it looks clean to me, but I don't know how to implement yet.
The reason I came up with this is because I need to know if Bar exists or not before adding Foo to the database. I wanted the classes according to the SOLID-principles (each class has it's own responsibilities). Or is it better to inject each service in the Logic so, like this:
public class FooLogic
{
private readonly IFooService _fooService;
private readonly IBarService _barService;
public FooLogic(IFooService fooService, IBarService barService) {
_fooService = fooService;
_barService = barService;
}
public void CreateFoo(Foo foo){
//Check if bar exists
if(_barService.ReadBar())
_fooService.AddFoo(foo);
else
//nothing
}
}
Maybe you have a complete different but better approach, let me know! I appreciate code examples :)
Keep it simple!
Create FooService that implements IFooService.
FooLogic should be removed. You can implement the logic inside the method CreateFoo.
Since FooService will impement all the methods, you can call ReadBar() instead of _barService.ReadBar(), there is no need for composition since you already have IFooService inheriting from all other interfaces.
This way, we are still respecting the dependency injection pattern.
I keep running into this scenario: suppose I have interface IFoo and several implementations, like RedFoo : IFoo and BlackFoo : IFoo. I then have classes that take IFoo in the constructor:
class BlackFooUser
{
public BlackFooUser(IFoo foo, other_parameters_here) {...}
}
class RedFooUser
{
public RedFooUser(IFoo foo, other_parameters_here) {...}
}
How do I tell the container to resolve all other parameters as usual, but always use BlackFoo when constructing BlackFooUser, and always use RedFoo when constructing RedFooUser? I know I can use ParameterOverride when calling Resolve(), but I want it to be the same whenever a Red/BlackFooUser is resolved, so this should go into RegisterType or RegisterFactory.
I can do something like
container.RegisterFactory<RedFooUser>(c=>new RedFooUser(c.Resolve<RedFoo>(), other_parameters_here));
but this is quite verbose, and this will have to change every time I add new parameters.
Is there a better way?
UPDATE I am specifically looking to do this through container registrations, without modifying the classes involved. There are multiple reasons for that, but it boils down to this:
Encoding dependency information in the classes violates separation of concerns
It usually scales poorly in case of many classes and many dependencies
It puts limits to how the classes can be composed
It restricts me to classes that I own the source to and can modify at will
Use an abstract class and generics to force a specific type.
Unity will automatically resolve a concrete type, so you don't need to register these.
public abstract class FooUser<TFoo> where TFoo : IFoo
{
private readonly TFoo _foo;
public FooUser(TFoo foo, other parameters)
{
_foo = foo;
}
}
public class BlackFooUser : FooUser<BlackFoo>
{
public BlackFooUser (BlackFoo foo, other parameters)
: base(foo, other parameters)
{
}
}
public class RedFooUser : FooUser<RedFoo>
{
public RedFooUser (RedFoo foo, other parameters)
: base(foo, other parameters)
{
}
}
Full reproduction below - output is:
Constructed RedFooUser with foo 'RedFoo' and otherParameter 'I'm the other parameter'
Constructed BlackFooUser with foo 'BlackFoo' and otherParameter 'I'm the other parameter'
void Main()
{
var container = new UnityContainer()
.RegisterInstance<string>("I'm the other parameter");
var foo1 = container.Resolve<RedFooUser>();
var foo2 = container.Resolve<BlackFooUser>();
}
// Define other methods, classes and n
public interface IFoo
{
}
public class BlackFoo : IFoo { }
public class RedFoo : IFoo { }
public abstract class FooUser<TFoo> where TFoo : IFoo
{
private readonly TFoo _foo;
public FooUser(TFoo foo, string otherParameter)
{
_foo = foo;
Console.WriteLine($"Constructed {GetType().Name} with foo '{foo.GetType().Name}' and otherParameter '{otherParameter}'");
}
}
public class BlackFooUser : FooUser<BlackFoo>
{
public BlackFooUser(BlackFoo foo, string otherParameter)
: base(foo, otherParameter)
{
}
}
public class RedFooUser : FooUser<RedFoo>
{
public RedFooUser(RedFoo foo, string otherParameter)
: base(foo, otherParameter)
{
}
}
When you register your types, you can give them a name, and then refer to that name in the constructors where those types get injected. Something like this:
public class BlackFoo : IFoo
{
public const string UNITY_KEY = "BlackFoo";
}
In your container registration:
_container.RegisterType<IFoo, BlackFoo>(BlackFoo.UNITY_KEY, new ContainerControlledLifetimeManager());
In your constructor:
public class BlackFooUser
{
public BlackFooUser([Dependency(BlackFoo.UNITY_KEY)] IFoo foo)
{
}
}
This ensures that when the container does the dependency injection, it will use the named IFoo registration.
I submitted an issue to UnityContainer repo, and the response by Eugene Sadovoy pushed me towards this answer.
To avoid an infinite loop, one can register the default factory as named registration, and invoke it from the default, unnamed factory, along the lines of (sorry, I changed the names a little compared to the question):
container
.RegisterType<SpecialFooUser>("stdreg")
.RegisterFactory<SpecialFooUser>(
c => c.Resolve<SpecialFooUser>("stdreg",
new DependencyOverride<IFoo>(c.Resolve<SpecialFoo>()))
);
This works, but looks quite verbose, so I wrote a few extension methods and classes (~100 lines of code total) to make it less verbose and more expressive:
container.Register(
new CustomFactory<SpecialFooUser>()
.DependencyOverride<IFoo, SpecialFoo>());
The complete source code is on GitHub: https://github.com/ikriv-samples/UnityResolveOverrideFactory
While searching for ways to get an instance of a singleton class i found many different approaches (some simple, some convoluted) but when messing around i found a way to do it which i didn't find anywhere else.
So what i basically do is:
public class Foo
{
public static Foo Invoker;
public Foo()
{
Invoker = this;
}
public void Method1()
{
//.....
}
}
And then from another class
public class Foo2
{
public Foo2()
{
//.....
}
public void Main()
{
var foo = Foo.Invoker;
//or
Foo.Invoker.Method1();
}
}
My app is single threaded so i don't care about thread safety (should i?) , so are there any other problems that this approach could cause that i am missing?
First of all, your 'singleton' pattern is quite easy to break. Let's say I'd create two instances of Foo in your application (changing the name of the class Foo1 to Bar for clarity):
var firstFoo = new Foo();
var bar = new Bar();
// Will access firstFoo when it calls Foo.Invoker
bar.Main();
var secondFoo = new Foo();
// Will access secondFoo when it calls Foo.Invoker. Huh?
bar.Main();
Another problem: Let's say I use Bar, without having initialized any Foo instances:
var bar = new Bar();
// Will throw a NullReferenceException, because Foo.Invoker is not yet initialized.
bar.Main();
As a rough rule of thumb, you should not set static fields from instances, because it leads to these kinds of situations.
Secondly, Bar probably does not need to know that Foo is a singleton in the first place. You could simply inject Foo in Bar's constructor.
public class Bar
{
private Foo foo;
public Bar(Foo foo) => this.foo = foo ?? throw new ArgumentNullException(nameof(foo));
public void Main()
{
// Now we know it is not null and, for Bar, it does not matter whether it's a singleton or not.
foo.Method1();
}
}
This way you could manage Foo instances easier in your application:
var firstFoo = new Foo();
var bar = new Bar(firstFoo);
// Does not make a difference now.
var secondFoo = new Foo();
This way, you could also leverage dependency injection containers like NInject or Microsoft.Extensions.DependencyInjection to manage your singletons for you.
If you really do want to create a single threaded singleton pattern, I would read Jon Skeet's blog post about singletons (good read!).
The simplest way of creating a singleton would be this approach. This way you create a single instance of Foo on the static property, that can never be changed. But read the blog post for more advanced patterns:
public class Foo
{
public static Foo Invoker { get; } = new Foo();
// Private constructor makes sure the only instance of Foo is created here.
private Foo()
{
}
}
Edit
If you'd want to make sure that all references to Foo in your application point to the last created instance of Foo, you could try something like this:
interface IFoo
{
void Method1();
}
class Foo : IFoo
{
private static int index = 1;
private int id;
private static NestedFoo invoker = new NestedFoo();
public static IFoo Invoker
{
get
{
if (invoker.Instance == null)
{
Create();
}
return invoker;
}
}
private Foo(int id) => this.id = id;
public static IFoo Create()
{
var foo = new Foo(index++);
invoker.Instance = foo;
return invoker;
}
public void Method1()
{
Console.WriteLine(this.id);
}
private class NestedFoo : IFoo
{
public Foo Instance { get; set; }
public void Method1() => Instance.Method1();
}
}
Now you'll always have a reference to the same instance of foo:
var foo = Foo.Create();
foo.Method1(); // 1
var foo2 = Foo.Create();
foo.Method1(); // 2
foo2.Method1(); // 2
I have a pattern that comes up all the time when I'm working. I am almost exclusively a web developer, and Ninject's InRequestScope handles 99% of my needs.
Here's the pattern:
// abstractions
interface IFoo {
void FooMe();
int GetSomeValue();
}
interface IBar {
void BarMe();
}
interface IFooBar {
void FooAndBar();
}
// concrete classes
class Foo : IFoo {
public void FooMe() { Console.WriteLine("I have fooed"); }
public void GetSomeValue() { return 123; }
}
class Bar : IBar {
private readonly IFoo _Foo;
public Bar(IFoo foo) { _Foo = foo; }
public void BarMe() { Console.WriteLine("Bar: {0}", _Foo.GetSomeValue()); }
}
class FooBar : IFooBar {
private readonly IFoo _Foo;
private readonly IBar _Bar;
public Bar(IFoo foo, IBar bar) { _Foo = foo; _Bar = bar; }
public void FooAndBar() {
_Foo.FooMe();
_Bar.BarMe();
}
}
// bindings
kernel.Bind<IFoo>().To<Foo>();
kernel.Bind<IBar>().To<Bar>();
kernel.Bind<IFooBar>().To<FooBar>();
What I want to do is set it up such that every time I kernel.Get<IFooBar> it creates exactly one Foo and injects it into the constructors of both Bar and FooBar.
I've experimented with this off and on using the Named Scope extension, but I've never been able to get it to work.
What is the proper binding syntax for this?
so what you've got to do is define some name:
const string FooBarScopeName = "FooBarScope";
and then define the scope:
kernel.Bind<IFooBar>().To<FooBar>()
.DefinesNamedScope(FooBarScopeName);
and bind the Foo in the named scope (the name must match!):
kernel.Bind<IFoo>().To<Foo>();
.InNamedScope(FooBarScope);
Alternative:
There's also InCallScope() which can be used if there's one kernel.Get() for each time a IFooBar is created. In that case, simply do:
kernel.Bind<IFoo>().To<Foo>().InCallScope();
I'm trying to resolve a known fixed list of Foo services (in singleton scope) using NInject; this resolution happens in a FooProvider's constructor. The problem is that each Foo will need this provider as well.
public interface IFoo { }
public interface IFooProvider { }
public class Foo : IFoo
{
private readonly IFooProvider _provider;
public Foo(IFooProvider provider)
{
_provider = provider;
}
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
public class Program
{
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}
}
There is a logical cyclic loop here, and obviously the stack overflow shows its going down it. However, I have both interface bound to singletons.
Thinking about it; we try to resolve IFoo, which then needs resolution of IFooProvider, itself needing a list of IFoo... but we haven't resolved for any IFoo singletons yet because we're still trying to resolve it!
So how could I work around this?
[Edit] Possible solution; delay buffering of IFoo service instances.
public FooProvider(IKernel kernel)
{
_kernel = kernel;
}
public IFoo Find(object context)
{
if (_allFooServices == null)
_allFooServices = _kernel.GetAll<IFoo>().ToList();
return _allFooServices.Where(...
[Why?]
The general idea is to avoid the service locator pattern, as I've seen it described as an anti-pattern. So, rather than try to resolve services through the dependency injector during run time; you try to get a list of services during setup. The problem with this though, is that if any of your services want to find other services, you have the above problem.
You cannot resolve this cyclic dependency with Ninject. You are not even able to create such object graph by hand.
First you have to remove the cyclic dependency from at least one constructor. You can move this dependency to property and use property injection.
public class Foo : IFoo
{
[Inject]
public IFooProvider Provider { get; set; }
}
If you want to avoid service-locator pattern you should remove dependency on IKernel from the constructor of FooProvider and use the injection of collection of registered IFoo implementations instead.
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IEnumerable<IFoo> fooServices)
{
_allFooServices = fooServices.ToList();
}
}
You could use property injection with one of them.
public interface IFoo
{
}
public interface IFooProvider
{
}
public class Foo : IFoo
{
[Inject]
public IFooProvider Provider { get; set; }
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}
Really this seems like bad design, but to answer your question directly, don't instantiate _allFooServices in the constructor. You can do something like this:
private List<IFoo> _allFooServices;
private List<IFoo> AllFooServices
{
get { return _allFooServices ?? (_allFooServices = Kernel.GetAll<IFoo>().ToList()) }
}
Perhaps you can choose a more concrete example, rather than Foo.