structuremap configuration to substitute only 1 dependency - structuremap

If I have a class with lots of dependencies, e.g:
public ClassWithManyDependencies(IDependencyA a, IDependencyB b,
IDependencyC c, IDependencyD d,
IDependencyE e, IDependencyF f,
IDependencyG g, IDependencyH h): IClassWithManyDependencies
{
// constructor code...
}
when I want to inject a different implementation of just one of those dependencies (say IDependencyH) - and I want dependencies on IDependencyH in other classes to use the default implementation - I am currently doing this:
var specialVersionH = new DecoratedDependencyH();
For<IClassWithManyDependencies>().Use(c => new ClassWithManyDependencies(
c.GetInstance<IDependencyA>(),
c.GetInstance<IDependencyB>(),
c.GetInstance<IDependencyC>(),
c.GetInstance<IDependencyD>(),
c.GetInstance<IDependencyE>(),
c.GetInstance<IDependencyF>(),
c.GetInstance<IDependencyG>(),
specialVersionH));
Is there a more concise way to configure structuremap to use the default versions of each dependency except for a specified one?

This is for 2.6.
ForConcreteType<ClassWithManyDependencies>()
.Configure.Ctor<IDependencyH>()
.Is<DecoratedDependencyH>();
For<IClassWithManyDependencies>().Use(ctx => ctx.GetInstance<ClassWithManyDependencies>());
I ran a "simplified" test, seemed to work.

Related

language-ext Task of Either with multiple from clauses

I am learning FP with language-ext and I ran into a problem that I have not been able to overcome. I simplified my code down to this example:
using System;
using System.Threading.Tasks;
using LanguageExt;
using static LanguageExt.Prelude;
using Xunit;
namespace Temp {
public class SelectManyError {
[Fact]
public async Task Do() {
var six = await from a in Task.FromResult(Right<Exception, int>(1))
from b in Task.FromResult(Right<Exception, int>(2))
from c in Task.FromResult(Right<Exception, int>(3))
select a + b + c;
}
}
}
I am getting this error:
Multiple implementations of the query pattern were found for source type Task<Either<Exception, int>>. Ambiguous call to 'SelectMany'.
I understand what the compiler thinks the issue is from reading this webpage. But, I am clearly missing or not understanding something important because I cannot figure out how this error is caused by this scenario OR what to do about it. This will work just fine if it is only 2 from clauses, which confuses me even more.
Is this the wrong approach to this type of problem? Is there another way I am unaware of?
Lang-ext author here. We've been discussing the issue on the lang-ext github repo.
These are my comments:
It's tough. They're not really false positives to be honest, because Either<L, R> supports the + operator, and so the SelectMany that belongs to Task<R> will produce a valid result just like the SelectMany that works with Task<Either<L, R>>.
Basically the a, b, and c values could legitimately be int or Either<Exception, int> depending on which SelectMany implementation the compiler chooses.
The whole expression is valid for all SelectMany extensions, which is obviously why we have that ambiguity.
It's a shame that changing var three = ... to Either<Exception, int> three = ... doesn't change the inference system. Because that's the key difference between the two possible expressions that the compiler is confused by.
One thing you might want to do instead of using Task<Option<A>> is use OptionAsync<A> and instead of Task<Either<L, R>> use EitherAsync<L, R>. They're essentially exactly the same types, except it's got all the binding semantics wrapped up nicely so you'll never have this issue again.
I am going through the process of creating an *Async variant for all the monadic types in lang-ext. For convenience, potential performance benefits, and to allow the equivalent of 3 nested levels of monads: M<A<B<C>>> for example a Seq<OptionAsync<A>> is the same as Seq<Task<Option<A>>>.
Anyway, back to your example above, you could instead do:
public async Task<int> Method()
{
var six = from a in Right<Exception, int>(1).ToAsync()
from b in Right<Exception, int>(2).ToAsync()
from c in Right<Exception, int>(3).ToAsync()
select a + b + c;
return await six.IfLeft(0);
}
Or if you want to construct from a Task<int>:
public async Task<int> Method()
{
var six = from a in RightAsync<Exception, int>(Task.FromResult(1))
from b in RightAsync<Exception, int>(Task.FromResult(2))
from c in RightAsync<Exception, int>(Task.FromResult(3))
select a + b + c;
return await six.IfLeft(0);
}
Or, you could stay inside the monad and return that:
public EitherAsync<Exception, int> Method() =>
from a in RightAsync<Exception, int>(Task.FromResult(1))
from b in RightAsync<Exception, int>(Task.FromResult(2))
from c in RightAsync<Exception, int>(Task.FromResult(3))
select a + b + c;
The compiler is having a hard time understanding what the type of a is supposed to be (either int or Either<Exception, int>) since it is unused on the second from line.
Here is a awfully ugly workaround for this specific case. However, for any type, I think the hack can be adapted to work for that type.
using System;
using System.Threading.Tasks;
using LanguageExt;
using Xunit;
using static LanguageExt.Prelude;
public class Namespace
{
[Fact]
public async Task Method()
{
var six = await from a in Right<Exception, int>(1).AsTask()
from b in Right<Exception, int>(a - a + 2).AsTask()
from c in Right<Exception, int>(3).AsTask()
select a + b + c;
}
}
Another way to work around this is by using how the compiler searches for matching extension methods.
From the C# spec
The search [..] proceeds as follows:
Starting with the closest enclosing namespace declaration, continuing with each enclosing namespace declaration, and ending with the containing compilation unit, successive attempts are made to find a candidate set of extension methods:
If the given namespace or compilation unit directly contains non-generic type declarations Cᵢ with eligible extension methods Mₑ, then the set of those extension methods is the candidate set.
If namespaces imported by using namespace directives in the given namespace or compilation unit directly contain non-generic type declarations Cᵢ with eligible extension methods Mₑ, then the set of those extension methods is the candidate set.
So .. if you add your own version of the extension methods needed for the LINQ query syntax to work (Select and SelectMany) within your application, at the same or a higher level in the namespace hierarchy as the calling code, these will be used and the two ambiguous versions in the LanguageExt namespace will never be considered.
Your extensions can just delegate to the generated source code in LanguageExt.Transformers.
Here I'm using Task<Validation< rather than Task<Either<; just check the source-code for the extensions class name of the particular combination of stacked monads you are using:
using System;
using System.Threading.Tasks;
using LanguageExt;
namespace YourApplication;
public static class BindDisambiguationExtensions
{
public static Task<Validation<FAIL, B>> Select<FAIL, A, B>(
this Task<Validation<FAIL, A>> ma,
Func<A, B> f) =>
ValidationT_AsyncSync_Extensions.Select(ma, f);
public static Task<Validation<FAIL, C>> SelectMany<FAIL, A, B, C>(
this Task<Validation<FAIL, A>> ma,
Func<A, Task<Validation<FAIL, B>>> bind,
Func<A, B, C> project) =>
ValidationT_AsyncSync_Extensions.SelectMany(ma, bind, project);
}

Agatha RRSL and StructureMap 3.0

I want to use Agatha RRSL with my implementation of the StructureMap 3.0 wrapper to Agatha's IoC container. Agatha has NuGet packages with StructureMap 2.6 which I do not like.
I started by copy/pasting the code from Agatha.StructureMap source code and proceeded to make the changes to use 3.0 StructureMap.
The issue I now have is that I get a StructureMapException
StructureMap.StructureMapBuildPlanException occurred
_HResult=-2146233088
_message=Unable to create a build plan for concrete type Agatha.Common.WCF.RequestProcessorProxy
HResult=-2146233088
IsTransient=false
Message=Unable to create a build plan for concrete type Agatha.Common.WCF.RequestProcessorProxy
new RequestProcessorProxy(InstanceContext, String endpointConfigurationName, String remoteAddress)
┗ InstanceContext = **Default**
String endpointConfigurationName = Required primitive dependency is not explicitly defined
String remoteAddress = Required primitive dependency is not explicitly defined
Source=StructureMap
Context=new RequestProcessorProxy(InstanceContext, String endpointConfigurationName, String remoteAddress)
┗ InstanceContext = **Default**
String endpointConfigurationName = Required primitive dependency is not explicitly defined
String remoteAddress = Required primitive dependency is not explicitly defined
Title=Unable to create a build plan for concrete type Agatha.Common.WCF.RequestProcessorProxy
StackTrace:
at StructureMap.Pipeline.ConstructorInstance`1.ToBuilder(Type pluginType, Policies policies) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\Pipeline\ConstructorInstance.cs:line 83
InnerException:
This looks to me as though the constructor StructureMap thinks it needs to use, but views as not properly configured, is the one with multiple parameters. In reality I need it to use the parameterless constructor.
However I think I've configured the constructor properly. Here is the code I use to configure a parameterless constructor for RequestProcessorProxy:
structureMapContainer.Configure(x => x.ForConcreteType<RequestProcessorProxy>().Configure.SelectConstructor(() => new RequestProcessorProxy()));
What may have gone wrong?
Just as heads up, I'm new to both StructureMap and Agatha so I may have misunderstood any or all of the above...
I've never used SelectConstructor so don't know how to make it working with it but if you want to make SM to use parameterless constructor then you can do it like this when you resolve concrete type:
var container =
new Container(
c => c.For<RequestProcessorProxy>().Use(() => new RequestProcessorProxy()));
or like this when you are resolving it by the interface:
var container =
new Container(
c => c.For<IRequestProcessor>().Use(() => new RequestProcessorProxy()));
I am not familiar with Agatha RRSL at all so I don't know whether I used good interface.
Hope this helps!

Dependency injection via Google Guice use case

I have code that looks like the ff.:
Interface i;
if (someCondition) {
ImplementationA a = new ImplementationA();
a.setFieldA(someValueA);
a.setFieldB(someValueB);
i = a;
} else {
ImplementationB b = new ImplementationB();
b.setFieldC(someValueC);
i = b;
}
// Do something with i.
My questions are:
Should I use dependency injection here or is this beyond the scope of the technique?
If I should use dependency injection here, how can I accomplish it using Google Guice?
dynamic runtime injection is out of scope. you will have to configure which implementation to use via Modules. You could still use a factory (have a look at multibindings and assisted injection) and save yourself the work to set up your instances though ...

Convention Based Dependency Injection with Ninject 3.0.0

I have two projects in my solution... a domain project and MVC3 web project (e.g. MyApp.Domain and MyApp.Web). Previously, when using Ninject.Extensions.Conventions ver. 2, I was able to use the following statement in the NinjectMVC3.cs file, and required dependencies throughout my solution (both web and domain) were injected properly (e.g. IFoo automatically bound to Foo).
kernel.Scan(x =>
{
x.FromAssembliesMatching("*");
x.BindWith<DefaultBindingGenerator>();
});
I have just upgraded to Ninject 3.0.0 (pre-release) and Ninject.Extensions.Conventions 3.0.0 (another pre-release) but the syntax for convention based binding has changed. I have figured out that I can use the following statement with the new version, but it only automatically binds the convention based interfaces in MyApp.Web and not in MyApp.Domain. The previous version bound interfaces throughout the application.
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.BindToAllInterfaces());
Any clue how I can configure convention based binding with the new Ninject version? I assume it has to do with specifying the assembly, but I have tried using FromAssembliesMatching("*") and it fails for everything then.
-- Edit to show my exisiting code in RegisterServices method: --
private static void RegisterServices(IKernel kernel)
{
// This code used to work with v.2 of Ninject.Extensions.Conventions
// kernel.Scan(x =>
// {
// x.FromAssembliesMatching("*");
// x.BindWith<DefaultBindingGenerator>();
// });
// This is the new v3 code that automatically injects dependencies but only for interfaces in MyApp.Web, not MyApp.Domain
kernel.Bind(x => x.FromThisAssembly().SelectAllClasses().BindToAllInterfaces());
// I tried this code, but it throws "Error activating IDependencyResolver" at "bootstrapper.Initialize(CreateKernel)"
// kernel.Bind(x => x.FromAssembliesInPath(AppDomain.CurrentDomain.RelativeSearchPath).SelectAllClasses().BindToAllInterfaces());
// These are dependencies in MyApp.Web that ARE being bound properly by the current configuration
// kernel.Bind<IMemberQueries>().To<MemberQueries>();
// kernel.Bind<IGrantApplicationQueries>().To<GrantApplicationQueries>();
// kernel.Bind<IMailController>().To<MailController>();
// These are dependencies in MyApp.Domain that ARE NOT being bound properly by the current configuration, so I have to declare them manually
// They used to be injected automatically with version 2 of the conventions extention
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
kernel.Bind<IMemberServices>().To<MemberServices>();
kernel.Bind<IGrantApplicationServices>().To<GrantApplicationServices>();
// These are dependencies that SHOULD NOT be bound by convention as they require a different scope or have unique naming
kernel.Bind(typeof(EfDbContext)).ToSelf().InRequestScope();
kernel.Bind<IConfigurationProvider>().To<WebConfigConfigurationProvider>().InSingletonScope();
kernel.Bind<IAuthorizationProvider>().To<MyAppAuthorizationProvider>();
kernel.Bind<IPrincipal>().ToMethod(ctx => HttpContext.Current.User).InRequestScope();
kernel.Bind<IGrantApplicationDocumentServices>().To<MySpecialNameGrantAplicationDocumentServices>().InRequestScope();
}
The equivalent is:
kernel.Bind(x => x
.FromAssembliesMatching("*")
.SelectAllClasses()
.BindDefaultInterface());

Dependency injection - need larger example?

i'm looking for a larger example of dependency injection and how it can be implemented. If class A depends on class B and passes a reference of class C to B's constructor, must not class A also take a reference to class C in it's constructor? This means that the main method in the application should create all classes really, which sounds wierd?
I understand that using DI frameworks we can have it in XML files somehow, but that sounds like it could be hard to quickly see what type that really is instanciated? Especially if it a very large application.
You are correct and each DI framework has a different way of managing it.
Some use attributes on the properties etc to denote dependency and then "automagically" supply an instance of the correct type, while others (say castle windsor for .net) allow xml configuration, fluent or other methods for "wiring up" the dependency graph.
Also no, class A takes a built reference to an instance of B which was built using an instance of C. A needs to know nothing about C unless exposed via B.
public class C { }
public class B { public B(C c) { ... }}
public class A { public A(B b) { ... }}
// manual wireup
C c = new C();
B b = new B(c);
A a = new A(b);
// DI framework
InversionOfControlContainer container = new InversionOfControlContainer(... some configuration);
A a = container.ResolveInstanceOf<A>();
// container dynamically resolves the dependencies of A.
// it doesnt matter if the dependency chain on A is 100 classes long or 3.
// you need an instance of A and it will give you one.
Hope that helps.
to answer your question about classes A,B,and C, A only needs a reference to B.
Most DI frameworks do not require you to use XML for configuration. In fact, many people prefer not to use it. You can explicitly set things up in code, or use some kind of conventions or attributes for the container to infer what objects should fulfil dependencies.
Most DI frameworks have a facility for "lazy loading" to avoid the creation of every single class up front. Or you could inject your own "factory or builder" objects to create things closer to the time when they will be used
You've not said what language you are using. My example below is in C# using the Unity container. (obviously normally you would use interfaces rather than concrete types):
container = new UnityContainer();
container.RegisterType<C>();
container.RegisterType<B>();
A a = container.Resolve<A>();
here's a few examples from the PHP Language, hope this helps you understand
class Users
{
var $Database;
public function __construct(Database $DB)
{
$this->Database = $DB;
}
}
$Database = Database::getInstance();
$Users = new Users($Database);
From this example the new keyword is used in the method getInstance(), you can also do
$Users = new Users(Database::getInstance());
Or another way to tackle this is
class Users
{
/*Dependencies*/
private $database,$fileWriter;
public function addDependency($Name,$Object)
{
$this->$Name = $Object;
return $this;
}
}
$Users = new Users();
$Users->addDependency('database',new Database)->addDependency('fileWriter',new FileWriter);
Update:
to be honest, I never use Dependency Injection as all its doing is passing objects into classes to create a local scope.
I tend to create a global entity, and store objects within that so there only ever stored in 1 variable.
Let me show you a small example:
abstract class Registry
{
static $objects = array();
public function get($name)
{
return isset(self::$objects[$name]) ? self::$objects[$name] : null;
}
public function set($name,$object)
{
self::$objects[$name] = $object;
}
}
Ok the beauty of this type of class is
its very lightweight
it has a global scope
you can store anything such as resources
When your system loads up and your including and initializing all your objects you can just store them in here like so:
Registry::add('Database',new Database());
Registry::add('Reporter',new Reporter());
Where ever you are within your runtime you can just use this like a global variable:
class Users
{
public function getUserById($id)
{
$query = "SELECT * FROM users WHERE user_id = :id";
$resource = Registry::get("Database")->prepare($query);
$resource->bindParam(':id',$id,PDO::PARAM_INT);
if($resource->execute())
{
//etc
}else
{
Registry::get('Reporter')->Add("Unable to select getUserById");
}
}
}
i see this way of object passing is much cleaner
If anybody is still looking for a good example which shows DI without IoC Containers (poor man's DI) and also with IoC Container (Unity in this example) and registering the types in code and also in XML you can check this out: https://dannyvanderkraan.wordpress.com/2015/06/15/real-world-example-of-dependeny-injection/

Resources