Autofac vs. Structuremap, how do I inject all instances of an interface? - structuremap

In autoFac, I can register multiple implementation of an interface. When autofac instantiates my object, all instances are passed to the constructor.
From autofac’s documentation: here
For example, when Autofac is injecting a constructor parameter of type
IEnumerable it will not look for a component that supplies
IEnumerable. Instead, the container will find all
implementations of ITask and inject all of them.
Is this functionality available in StructureMap?
For my classes:
public interface IFoo
{
}
public class Foo1 : IFoo
{
}
public class Foo2 : IFoo
{
}
public class UsingFoo
{
public UsingFoo(IEnumerable<IFoo> allFoos)
{
foreach (var foo in allFoos)
{
}
}
}
How do I register my implementations, so that when UsingFoo is instantiated, the constructor will be passed all implementations of IFoo?

In StructureMap you can do:
ObjectFactory.Intialize(x => x.Scan(y => y.AddAllTypesOf<IFoo>()));
That will register all types of IFoo
Then when you resolve UsingFoo, they will be injected.
Edit:
I just quickly wrote this up in a console app:
ObjectFactory.Initialize(x =>
{
x.Scan(y =>
{
y.AddAllTypesOf<IFoo>();
});
});
var usingFoo = ObjectFactory.GetInstance<UsingFoo>();
Edit:
You made me doubt myself, so I double checked.
It works fine.
Here's a working example I quickly wrote in a console app:
public interface IFoo
{
string Text { get; }
}
public class Foo1 : IFoo
{
public string Text
{
get { return "This is from Foo 1"; }
}
}
public class Foo2 : IFoo
{
public string Text
{
get { return "This is from Foo 2"; }
}
}
public class Bar
{
private readonly IEnumerable<IFoo> _myFoos;
public Bar(IEnumerable<IFoo> myFoos)
{
_myFoos = myFoos;
}
public void Execute()
{
foreach (var myFoo in _myFoos)
{
Console.WriteLine(myFoo.Text);
}
}
}
class Program
{
static void Main(string[] args)
{
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
x.Scan(y =>
{
y.TheCallingAssembly();
y.AddAllTypesOf<IFoo>();
});
});
var myBar = ObjectFactory.GetInstance<Bar>();
myBar.Execute();
Console.WriteLine("Done");
Console.ReadKey();
}
}
The output is:
This is from Foo 1
This is from Foo 2
Done

Related

Interface with more implementation and Dependency Injection

I created a project with .net Core 2.
Now I have a List of classes from the same interface which I needed at runtime.
My problem is, I can't add this classes to the servicecollection (only one interface). So I don't have access to the other services in those classes. Also I think it wouldn't solve it.
I could create a singleton/static class with my servicecollection and use the IServiceProvider to get those other services from there, but I think that isn't the best practice.
Here is an example of my problem:
public class Manager : IManager
{
private IList<IMyService> _myService;
public Manager()
{
IList<Type> types = GetIMyServiceTypes();
foreach (Type type in types)
{
var instance = (IMyService)Activator.CreateInstance(type);
_myService.Add(instance)
}
}
public IList<bool> IsTrue()
{
return _myService
.Select(se => se.IsTrue())
.ToList();
}
public IList<Type> GetIMyServiceTypes()
{
var type = typeof(IMyService);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p))
.ToList();
return types;
}
}
public class ServiceType1: IMyService
{
public bool IsTrue()
{
//Need Access to IServiceCollection Services
}
}
public interface IMyService
{
bool IsTrue();
}
public class MyController : Controller
{
private IManager _amanager;
public MyController(IManager manager)
{
_manager = manager
}
public IActionResult IsTrue()
{
IList<bool> isTrue =_manager.IsTrue();
return new ObjectResult(isTrue);
}
}
Is there a pattern, which I could use to solve my problem? Is there a best practice to have access to the services without using them in the constructor?
I found the solution on another post in stackoverflow https://stackoverflow.com/a/44177920/5835745
But I will post my changes for other people with the same problem. I loaded the list of classes from the configuration, but it's also possible to add all classes.
public class Manager : IManager
{
private IList<IMyService> _myService;
private readonly Func<string, IService> _serviceAccessor;
public Manager (Func<string, IService> serviceAccessor)
{
IList<string> authentications = new List<string> {"value1", "value2"}
foreach (string authentication in authentications)
{
AddAuthentication(_serviceAccessor(authentication));
}
}
public IList<bool> IsTrue()
{
return _myService
.Select(se => se.IsTrue())
.ToList();
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<Value1>();
services.AddTransient<Value2>();
services.AddTransient(factory =>
{
Func<string, IService> accesor = key =>
{
switch (key)
{
case "value1":
return factory.GetService<Value1>();
case "value2":
return factory.GetService<Value2>();
default:
throw new KeyNotFoundException();
}
};
return accesor;
});
}
}

How do I use GetAll with Ninject so that one failure doesn't stop the other bindings from resolving?

Some of the provided bindings for the mutli injection may fail to resolve.
public List<IMyCommand> GetMyCommands()
{
//throws
return kernel.GetAll<IMyCommand>().ToList();
}
I want to still get all the successfully resolved objects, and ideally which ones failed. Is there a way to achieve this with Ninject?
Not out of the box.
But we can create some kind of hack/Workaround. Caution. I would rather implement some specific mechanism which handles my case explicitly than to involve Ninject in that.
But for the curiuous minded, here you go:
If you have a look at the implementation of IResolutionRoot.TryGet you'll see that all it does is catch ActivationException and return default(T) in that case.
We can create our own TryGetAll<T> which does the same, but not for the entire IRequest but rather for each binding separately. So here's how to do it:
public static class ResolutionRootExtensions
{
public static IEnumerable<T> TryGetAll<T>(this IResolutionRoot resolutionRoot)
{
var request = resolutionRoot.CreateRequest(
typeof(IFoo),
x => true,
Enumerable.Empty<IParameter>(),
true,
false);
IEnumerable results = resolutionRoot.Resolve(request);
IEnumerator enumerator = results.GetEnumerator();
while (MoveNextIgnoringActivationException(enumerator))
{
yield return (T)enumerator.Current;
}
}
private static bool MoveNextIgnoringActivationException(
IEnumerator enumerator)
{
while (true)
{
try
{
return enumerator.MoveNext();
}
catch (ActivationException)
{
}
}
}
}
I've tested it and it works:
public class Test
{
[Fact]
public void Foo()
{
var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<FooA>();
kernel.Bind<IFoo>().To<FooWithDependencyD>();
kernel.Bind<IFoo>().To<FooB>();
kernel.Bind<IFoo>().To<FooC>();
kernel.Bind<IFoo>().To<FooWithDependencyE>();
kernel.TryGetAll<IFoo>().Should()
.HaveCount(3)
.And.Contain(x => x.GetType() == typeof(FooA))
.And.Contain(x => x.GetType() == typeof(FooB))
.And.Contain(x => x.GetType() == typeof(FooC));
}
}
public interface IFoo
{
}
class FooA : IFoo { }
class FooB : IFoo { }
class FooC : IFoo { }
class FooWithDependencyD : IFoo
{
private readonly IDependency _dependency;
public FooWithDependencyD(IDependency dependency)
{
_dependency = dependency;
}
}
class FooWithDependencyE : IFoo
{
private readonly IDependency _dependency;
public FooWithDependencyE(IDependency dependency)
{
_dependency = dependency;
}
}
internal interface IDependency
{
}

Swapping nested dependency when requesting a specific object in StructureMap 3

I am trying to swap a nested dependency when resolving a specific instance using StructureMap. In 2.x I was able to do this with the following UseSpecial code, but it does not work in 3.x
The code is basically saying... when requesting an instance of IObject, swap the default instance for ITwo with AnotherTwo which is a dependency of IObject's dependency.
public class MyStructureMapRegistry : Registry
{
public MyStructureMapRegistry()
{
For<IObject>().UseSpecial(cfg => cfg.ConstructedBy(x =>
{
x.RegisterDefault(typeof(ITwo), x.GetInstance<AnotherTwo>());
return x.GetInstance<DependsOnOne>();
}));
}
}
The following is the sample object graph that I am trying to wire up.
public interface IObject { }
public interface IOne { }
public interface ITwo { }
public class DependsOnOne : IObject
{
IOne _one;
public DependsOnOne(IOne one)
{
_one = one;
}
}
public class DependsOnTwo : IOne
{
ITwo _two;
public DependsOnTwo(ITwo two)
{
_two = two;
}
}
public class Two : ITwo { }
public class AnotherTwo : ITwo { }

StructureMap Dependencies for Arguments in Constructor

If I have the following, and I were to say ObjectFactory.GetInstance<Master>() is it possible to tell StructureMap to make the I_A instance to A_User the same instance as the I_A passed to Master?
public interface I_A { }
public interface I_B { }
public class A_User {
public A_User(I_A A) { }
}
public class Master {
public Master(I_A _, I_B __, A_User ___) { }
}
The default behavior of StructureMap will always give you the same instance within a "build session" (effectively, a single call to GetInstance). You should not have to configure anything extra to get the behavior you want.
If it is not working as you expect, please post more details, or mention it on the StructureMap mailing list.
UPDATED:
As #Joshua Flanagan points out below, this is default SM behaviour. The following unit tests show that. The first tests uses the default behaviour. The second shows how you would get a unique instance if you wanted it:
using System;
using System.Collections.Generic;
using NUnit.Framework;
using StructureMap;
using StructureMap.Pipeline;
namespace SMTest
{
[TestFixture]
public class TestSOQuestion
{
class Foo : IFoo { }
interface IFoo { }
private interface IBar {
IFoo Foo { get; set; }
}
class Bar : IBar
{
public IFoo Foo { get; set; }
public Bar(IFoo foo)
{
Foo = foo;
}
}
class UsesFooAndBar
{
public IBar Bar { get; set; }
public IFoo Foo { get; set; }
public UsesFooAndBar(IFoo foo, IBar bar)
{
Foo = foo;
Bar = bar;
}
}
[Test]
public void TestOtherAnswer()
{
IContainer container = new Container(x =>
{
x.For<IFoo>().Use<Foo>();
x.For<IBar>().Use<Bar>();
});
var usesFooAndBar = container.GetInstance<UsesFooAndBar>();
Assert.AreSame(usesFooAndBar.Foo, usesFooAndBar.Bar.Foo);
}
[Test]
public void TestNonDefaultBehaviour()
{
IContainer container = new Container(x =>
{
x.For<IFoo>().AlwaysUnique().Use<Foo>();
x.For<IBar>().Use<Bar>();
});
var usesFooAndBar = container.GetInstance<UsesFooAndBar>();
Assert.AreNotSame(usesFooAndBar.Foo, usesFooAndBar.Bar.Foo);
}
}
}

Registering a Generics Implementation of a Generic Interface in StructureMap

i have a generic interface
public interface IDomainDataRepository<T>
{
T[] GetAll();
}
with a generic implementation
public class DomainDataRepository<T> : IDomainDataRepository<T>
{
public virtual T[] GetAll()
{
return GetSession().Linq<T>().ToArray();
}
}
how do I register it in StructureMap so that if I request IDomainDataRepository<State> then it will new up a DomainDataRepository<State>. Furthermore if I decide to implement a CountryDomainDataRepository and I request a IDomainDataRepository<Country> I want to get the specific implementation.
public class CountryDomainDataRepository : IDomainDataRepository<State>
{
public virtual Country[] GetAll()
{
return GetSession().Linq<Country>().ToArray();
}
}
You can accomplish this by configuring the generic open type to use a concrete open type:
[TestFixture]
public class open_generic_registration
{
[Test]
public void should_resolve_to_the_configured_concrete_instance_of_T()
{
var container = new Container(cfg =>
{
cfg.For(typeof (IDomainDataRepository<>)).Use(typeof (DomainDataRepository<>));
});
container.GetInstance<IDomainDataRepository<string>>().ShouldBeOfType<DomainDataRepository<string>>();
container.GetInstance<IDomainDataRepository<int>>().ShouldBeOfType<DomainDataRepository<int>>();
container.GetInstance<IDomainDataRepository<DateTime>>().ShouldBeOfType<DomainDataRepository<DateTime>>();
}
}

Resources