Passing constructor parameter throught multiple objects while resolving in AutoFac - c#

i have difficulties getting my registration in AutoFac done.
Let`s say i have the following classes
class Foo : IFoo
{
public Foo(string test, IBar bar) {}
}
class Bar : IBar
{
public Bar(bool someFlag) {}
}
The issue I'm having now is that i don't know how to set this boolean 'someFlag' while resolving.
I am only able to create these objects and fill in the flag while resolving, not while registering the classes.
Note: This is just an easy example to show the problem. In my case there are half a dozen classes in between Foo and Bar.
Can anyone please help me?
I know how to fill a parameter directly like the string 'test'. But I don`t understand how i pass the boolean through Foo to Bar.

Related

Extend a generic partial class

my question could seem strange.
I use a class to encapsulate a method to not have to build a class of the interface (it's a bit long to explain and i don't want to go too far).
I would to know if it was possible to "extend" a generic class by add partial to "extend" its generic part. The purpose is to keep the same name class, but by add one (or more in the future) generic type to have the possibility to encapsulate any method, then pass the object containing the function and that include this interface.
I need to have:
new Foo<string>()
new Foo<string, int>()
...
I 'successful' made this i think, but perhaps it will generate some bug i can't imagine right now, or perhaps it's not.. how to say a good way to program.
Example:
Original
// A class to encapsulate a method "without parameter"
partial Foo<T>: Interface
{
public Func<Interface, T> FooLambda{ get; set; }
public virtual object Run()
{
return ToRun(this);
}
}
The method i need to pass (from another class)
void FooToEncapsulate(Interface patt)
{
//--- My code using an object with the interface pattern
}
Add another generic Type to Foo
The part to "extend" Foo
partial Foo<T,Y>: Foo<Y>
{
public new Func<Interface, T, Y> FooLambda{ get; set; }
public T Param {get;set;}
public override object Run()
{
return this.ToRun(this, Param);
}
}
The other method i need to pass (from another class)
void FooToEncaspulate(Interface patt, int param)
{
//--- My code using an object with the interface pattern
//--- and "param"
}
I have no problem for the while with this code, and i know it's something that could be strange, must i forget to use this technic, or could i think it was thought to work also like this ? Must i think if it compiles that means it's ok ? Is there another way to proceed like this without create a new class, and extend in same time on the generic part ?
(Sorry for my english)
Thx.
Edit:
I thought by using partial that could be a good idea, because i would to keep the same name for my class. After have read an answer and comment from Enigmativity, i tried without partial, and i have no errors relating to the name of the class when i compile.
If i well understand, the fact to add generic parameter to a class makes that create as many class than as "variants" depending on the generic type. "Partial" is useful to split code on several files on a basic class.
Is partial could be useful on code split with the same number of generic type ?
You don't need the word partial to extend a class with a single generic type to have two generic types. They are in fact two distinct classed.
This works fine:
class Foo<T>
{
}
class Foo<T, Y> : Foo<Y>
{
}
Now, as said in the comments, the rest of your code is quite flaky. If you can clean up the code I could provide you with a more answer that will be of more use to you.

Ninject: Get the instance injected to a parent object

I have a crazy dependency injection case which I'll explain, but first let me show you some code:
class Foo : IFoo
{
Foo(
IBar bar,
IFooContext context,
IService service)
{
...
}
}
class Service : IService
{
Service(
IBar bar)
{
...
}
}
I'm resolving dependencies using Ninject. All of the above are InTransientScope. IBar is provided by a factory method, which uses one of the IFooContext properties for creation. What I want to achieve is to have Service injected into Foo with the same IBar instance that was injected into Foo.
I have no idea how to achieve this with Ninject. Is it even possible? If not, I'm thinking about exposing IBar property in IService and setting it in Foo constructor, but honestly I don't like this idea.
I simplified my case for sake of...simplicity, but in reality Foo is Rebus message handler, IFooContext is a message context, IBar is a logger. I want to format logger messages so that they include ID from a Rebus message being handled. And I want both Foo's and Service's log events to have that ID.
This can be solved with Ninject.Extensions.NamedScope
kernel.Bind<IFoo>().To<Foo>().DefinesNamedScope("FooScope");
kernel.Bind<IBar>().To<Bar>().InNamedScope("FooScope");
Thanks to Nkosi who pointed me towards right direction, I've managed to get what I wanted:
Bind<IFoo>()
.To<Foo>
.InScope(ctx => FooContext.Current);
Bind<IBar>()
.ToMethod(ctx =>
{
var scope = ctx.GetScope() as IFooContext;
// Some logic to create Bar by IFooContext...
});
Bind<IService>()
.To<Service>
.InScope(ctx => FooContext.Current);
As I said, in reality Foo is a Rebus message handler. For my example that means, that for every Foo new IFooContext is created and also I have access to current one.
As for Jan Muncinsky's answer - I didn't test it, but from what I read from Ninject's documentation, it seems that it's also a valid solution for this problem.
Thank you.

Accessing a parent instance's properties?

Lets say I have a few classes that looks a bit like these:
This class I'll call the parent instance:
public class Foo : Disposable {
public Foo() {
Bars = new List<Bar>();
FullPath = string.empty;
}
public Foo(string szInfo) {
Bars = new List<Bar>();
ImportantInfo = szInfo;
}
~Foo() => this.Dispose(false);
/* IDisposible stuff cropped for simplicity */
public string ImportantInfo {get; internal set;}
public List<Bar> Bars {get; internal set;}
public void SomeContainerLoadMethod() {
/* Add some bars here */
Bars.Add( new Bar() );
Bars.Add( new Bar() );
/* etc... */
}
}
As you can see here, the parent instance Foo holds onto some Bar classes.
I'll call these Bar classes in the List<Bar> the child instance containers in this question. Here's the definition of the Bar class in the example code way:
public class Bar : Disposable {
Bar() { }
~Bar() => this.Dispose(false);
/* IDisposable stuff cropped for simplicity */
public string CoolBuff {get; internal set;}
public void SomeCoolStringBufMethod() {
/* Do something to populate CoolBuff, but I need ImportantInfo! */
}
}
How would I access ImportantInfo from the parent instance , in the child instance container's SomeCoolStringBufMethod() ?
Here are the complications to this problem:
Doing it without having to make a duplicate ImportantInfo property and pass it into the child instance container's constructor
Doing it without having to pass ImportantInfo in as an argument when the child instance's SomeCoolStringBufMethod() method is called from
the parent .
Is this possible, say with System.Reflection, to 'look up' the fact a Bar is a member of a Foo, and fetch Foo's ImportantInfo property ?
You can't.
The two options you list are really the only way to do it.
Remember that any class instance exists at an address in memory. Variables just tell your application where to look in memory for the data. So sure, you can use reflection to find the ImportantInfo property of an instance of Foo, but which instance? Where should it look for it in memory? You have to know where in memory to look.
You know where in memory to look by using a variable. So you need to pass a variable to Bar somehow.
If there was a way to use reflection to find every active instance of a class, you could use that to figure it out in a round-about way, but there is no way to do that.
A small note: when you pass a string to a method, you aren't creating a duplicate. More on that here if you're interested.
Short Answer is NO.
Long Answer is Theoretically Yes, but Practically No.
Because you Bar have no reference to Foo at all, so you can't even tell which Foo contain your Bar, you can't even tell if your Bar is referenced by any Foo at all.
In order to figure that all , you have to trace back who is referencing your Bar.
In Theory it could be done using technique like GC,but GC does reference search from Top to Bottom which means from GC root to Foo then to your Bar , is doesn't do Bottom to Top. You can build your external double linked GC like Foo,Bar Graphic.
In Practice this will take you huge amount of effort, after that, you are also facing the Challenge to manage your own GC cycle of your Foo``Bar graphic.
So Short Answer is NO.
Number two is the way to go. (And no, I'm not trying to be funny.)
...pass ImportantInfo in as an argument when the child instance's SomeCoolStringBufMethod() method is called from the parent.
Methods are how classes interact with each other. Having a reference to another object is merely a means to the end of being able to call its methods and access its properties.
There's good reasons why we don't usually create classes with circular references between them. Imagine, for example, Text.StringBuilder. What if it had a reference to the class that created it, regardless of how it obtained that reference - via the constructor, reflection, or anything else.
What would StringBuilder do with that reference? In order to do anything with that object other than call ToString() it would need to know the type of that object. But if it knows the type of that object then it implies that StringBuilder only works if it has a reference to that type of object. That means the class that depends on StringBuilder and StringBuilder can only be used in conjunction with each other.
Relating that back to your class: What does your child class need? Does Bar need a Foo? No. It needs a string. Any class that calls its method can give it a string. So why couple it to another class? One day you or someone else will need to make Bar work without a Foo and then you'll have a knot to untie.
If Bar depends on a Foo to get its ImportantProperty, that also makes unit testing very difficult. You'd have to create a Foo and then create a Bar so that the Bar can get its ImportantProperty from the Foo. If it depends on a string then it's easy to test. The test only has to create a string.
In your example, passing ImportantProperty to a Bar constructor wouldn't make sense because it's a writable property of Foo. That means Foo can change it, and then all the Bars will have a different property unless you create all new ones. (Perhaps the fact that ImportantProperty can change is the reason why you want a reference back to the parent, but passing a string to a method call still solves that problem.)
You can almost certainly make this work without the child containing its own reference to the parent. If it must have that reference then it would make sense to pass that reference to the constructor of the child.

Inject Array of Interfaces in Ninject

Consider the following code.
public interface IFoo { }
public class Bar
{
public Bar(IFoo[] foos) { }
}
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IFoo[]>().ToConstant(new IFoo[0]);
// ToConstant() is just an example
}
}
public class Program
{
private static void Main(string[] args)
{
var kernel = new StandardKernel(new MyModule());
var bar = kernel.Get<Bar>();
}
}
When I try to run the program I get the following exception.
Error activating IFoo
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IFoo into parameter foos of constructor of type Bar
1) Request for Bar
How can I inject / bind to an array in Ninject?
Thanks for your time.
Edit:
My application imports data which is created by a third party component.
The import process applies different kind of filters (e.g. implementations of different filter interfaces). The rules for filtering change quite often but are too complex to be done with pure configuration (and a master filter).
I want to make adding/editing filters as easy as possible. What I have is an assembly where all the filter implementations are located in. I tried to bind every filter interface to the following method (which provides an instance of every implementation of that filter type). Basically I want to avoid the need to change my Ninject module when I add/remove filter classes.
private IEnumerable<TInterface> GetInterfaceImplementations<TInterface>(IContext context)
{
return GetType().Assembly.GetTypes()
.Where(t => typeof (TInterface).IsAssignableFrom(t) && IsConcreteClass(t))
.Select(t => Kernel.Get(t)).Cast<TInterface>();
}
I am feeling a bit guilty in terms of bypassing the containers DI mechanism. Is this a bad practice? Is there a common practice to do such things?
Resolution:
I use a wrapper class as bsnote suggested.
Ninject supports multi injection which would resolve your issue. https://github.com/ninject/ninject/wiki/Multi-injection
public interface IFoo { }
public class FooA : IFoo {}
public class FooB : IFoo {}
public class Bar
{
//array injected will contain [ FooA, FooB ]
public Bar(IFoo[] foos) { }
}
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IFoo>().To<FooA>();
Bind<IFoo>().To<FooB>();
//etc..
}
}
This is largely a restatement of #bsnote's answer (which I've +1d) which may help in understanding why it works in this manner.
Ninject (and other DI / addin frameworks) have two distinct facilities:
the notion of either binding to a single unambiguous implementation of a service (Get)
A facility that allows one to get a set of services [that one then programmatically picks one of or aggregates across in some way] (GetAll / ResolveAll in Ninject)
Your example code happens to use syntax that's associated with 2. above. (e.g., in MEF, one typically use [ImportMany] annotations to make this clear)
I'd need to look in the samples (look at the source - its really short, clean and easy to follow) to find a workaround for this.
However, as #bsnote says, one way of refactoring your requirement is to wrap the array either in a container, or to have an object that you ask for it (i.e., a factory method or repository type construct)
It may also be useful for you to explain what your real case is - why is there a naked array ? Surely there is a collection of items construct begging to be encapsulated underlying all this - this question certainly doesnt come up much?
EDIT: There are a set of scanning examples in the extensions that I imagine would attack a lot of the stuff you're trying to do (In things like StructureMap, this sort of stuff is more integrated, which obviously has pros and cons).
Depending on whether you're trying to achieve convention over configuration or not, you might want to consider sticking a marker interface on each type of plugin. Then you can explicitly Bind each one. Alternately, for CoC, you can make the Module's Load() routine loop over the set of implementations you generate (i.e., lots of individual Gets) in your edit.
Either way, when you have the multiple registrations in place you can happily either 'request' a T[] or IEnumerable<T> and get the full set. If you want to achieve this explicitly (i.e., Service Locator and all it implies - like in you're doing, you can use GetAll to batch them so you're not doing the looping that's implicit in the way you've done it.
Not sure if you've made this connection or if I'm missing something. Either way, I hope it's taught you to stick some code into questions as it speaks > 1000 words :P
It was a problem for me as well. Ninject injects each item of an array instead of the array itself, so you should have a mapping defined for the type of array items. Actually there is no possibility to map the array as a type with the current version of Ninject. The solution is to create a wrapper around the array. Lazy class can be used for example if it suits you. Or you can create your own wrapper.
Since Array implements IReadOnlyList the following works.
// Binding
public sealed class FooModule: NinjectModule
{
public opverride void Load()
{
Bind<IReadOnlyList<IFoo>>().ToConstant(new IFoo[0]);
}
}
// Injection target
public class InjectedClass {
public InjectedClass(IReadOnlyList<IFoo> foos) { ;}
}

Extending a class, compiler complains Microsoft.MapPoint.PlugIns.PlugIn does not contain a

I'm following the tutorial's that come with the SDK for Microsoft Virtual Earth, and when I try to create a plugin like it says, the compiler won't let me.
I'm extending the class Microsoft.MapPoint.PlugIn.PlugIn and it has two abstract methods (that the tutorial doesn't talk about) which I have implemented. However, when I compile it, Visual Studio says
'Microsoft.MapPoint.PlugIns.PlugIn' does not contain a constructor that takes '0' arguments
How can I fix this?
You probably need to add a constructor that passes something to the base constructor; add:
class Foo : PlugIn {
public Foo() : base( //****** here
}
when you type base(, intellisense should tell you what you need to give the base-constructor.
edit from searching, you need:
public Foo (Host host)
: base(host)
{
}
If you have a constructor, you need to ensure that the a base class constructor that exists is being called. By default, I believe the compiler attempts to align constructors one for one, but if that's not the functionality you want or that constructor doesn't exist, you need to define the base class constructor to call.
public Class()
: base(/*variables here*/)
{
}

Categories