Coder Social home page Coder Social logo

ninject.extensions.factory's Introduction

Ninject

Build status codecov NuGet Version NuGet Downloads

Ninject is a lightning-fast, ultra-lightweight dependency injector for .NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner. By using Ninject to support your software's architecture, your code will become easier to write, reuse, test, and modify.

Write your code so it's flexible...

public class Samurai {
    public IWeapon Weapon { get; private set; }
    public Samurai(IWeapon weapon) 
    {
        this.Weapon = weapon;
    }
}

...and let Ninject glue it together for you.

public class WarriorModule : NinjectModule
{
    public override void Load() 
    {
        this.Bind<IWeapon>().To<Sword>();
    }
}

Features:

  1. Focused. Too many existing dependency injection projects sacrifice usability for features that aren't often necessary. Each time a feature is added to Ninject, its benefit is weighed against the complexity it adds to everyday use. Our goal is to keep the barrier to entry - the baseline level of knowledge required to use Ninject - as low as possible. Ninject has many advanced features, but understanding them is not required to use the basic features.

  2. Sleek. Framework bloat is a major concern for some projects, and as such, all of Ninject's core functionality is in a single assembly with no dependencies outside the .NET base class library. This single assembly's footprint is approximately 85KB when compiled for release.

  3. Fast. Instead of relying on reflection for invocation, Ninject takes advantage of lightweight code generation in the CLR. This can result in a dramatic (8-50x) improvement in performance in many situations.

  4. Precise. Ninject helps developers get things right the first time around. Rather than relying on XML mapping files and string identifiers to wire up components, Ninject provides a robust domain-specific language. This means that Ninject takes advantage of the capabilities of the language (like type-safety) and the IDE (like IntelliSense and code completion).

  5. Agile. Ninject is designed around a component-based architecture, with customization and evolution in mind. Many facets of the system can be augmented or modified to fit the requirements of each project.

  6. Stealthy. Ninject will not invade your code. You can easily isolate the dependency on Ninject to a single assembly in your project.

  7. Powerful. Ninject includes many advanced features. For example, Ninject is the first dependency injector to support contextual binding, in which a different concrete implementation of a service may be injected depending on the context in which it is requested.

Everything else is in Extensions

Yes, sounds slim and focused, but where is the support for all the features that the competitors have?

Generally, they are maintained as specific focused extensions with owners who keep them in sync and pull in new ideas and fixes fast. These are summarized on the extensions section of the project website. Most are hosted alongside the core project right here.

License

Ninject is intended to be used in both open-source and commercial environments. To allow its use in as many situations as possible, Ninject is dual-licensed. You may choose to use Ninject under either the Apache License, Version 2.0, or the Microsoft Public License (Ms-PL). These licenses are essentially identical, but you are encouraged to evaluate both to determine which best fits your intended use.

Refer to LICENSE.txt for detailed information.

Changes history

Resources

ninject.extensions.factory's People

Contributors

danielmarbach avatar iappert avatar remogloor avatar scott-xu avatar theonesock avatar tothdavid avatar tschettler avatar ursenzler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ninject.extensions.factory's Issues

Castle.Core >= 5.0.0 seems to be incompatible

I have a solution with some direct references to Castle.Core version 4.4.1 and some direct references to Ninject.Extensions.Factory version 3.3.3. When I tried upgrading Castle.Core to 5.1.1 some unit tests started failing with an error about not locating the assembly for Castle.Core 4.0.0.0. After multiple attempts at updating binding redirects, deleting every bin and obj folder, rebuilding my solution and so on, I got build warnings related to conflicts with different versions of Castle.Core, and Ninject.Extension.Factory appeared in the message.
I've also tried with version 5.0.0 and got the same problems.
Ninject.Extensions.Factory 3.3.3 has a dependency for Castle.Core >= 4.2.0, but I wonder if for some reason it doesn't work with >= 5.0.0? Could someone confirm that? Thanks a lot!

troubles with adaptation Ninject.Extensions.Factory for .Net Core

At first, I adapted Ninject 3.2.3 for .Net Core. All Ninject tests passed green. Looks like there is no problem.
Next I adapted Ninject.Extensions.Factory for .Net Core. It compiles but Ninject.Extensions.Factory.Test fails.

Easiest example:

Running test Ninject.Extensions.Factory.FactoryTests.SingleBinding...
[xUnit.net 00:00:00.7008458] Starting: Ninject.Extensions.Factory.Test
[xUnit.net 00:00:01.1343741] Ninject.Extensions.Factory.FactoryTests.SingleBindingWhenUsingNineGenericBind [FAIL]
[xUnit.net 00:00:01.1361869] Ninject.ActivationException : Error activating IInterceptor using conditional implicit self-binding of IInterceptor
[xUnit.net 00:00:01.1363763] Provider returned null.
[xUnit.net 00:00:01.1365367] Activation path:
[xUnit.net 00:00:01.1367484] 2) Injection of dependency IInterceptor into parameter of constructor of type IWeaponFactoryProxy
[xUnit.net 00:00:01.1368207] 1) Request for IWeaponFactory
[xUnit.net 00:00:01.1368955]
[xUnit.net 00:00:01.1369682] Suggestions:
[xUnit.net 00:00:01.1370610] 1) Ensure that the provider handles creation requests properly.
[xUnit.net 00:00:01.1371871]
[xUnit.net 00:00:01.1387702] Stack Trace:
[xUnit.net 00:00:01.1407027] c:\projects\git\Ninject!Ninject 3.2.3 NetCore Working\Ninject\Activation\Context.cs(186,0): at Ninject.Activation.Context.ResolveInternal(Object scope)
[xUnit.net 00:00:01.1412330] c:\projects\git\Ninject!Ninject 3.2.3 NetCore Working\Ninject\Activation\Context.cs(160,0): at Ninject.Activation.Context.Resolve()
[xUnit.net 00:00:01.1413707] c:\projects\git\Ninject!Ninject 3.2.3 NetCore Working\Ninject\KernelBase.cs(400,0): at Ninject.KernelBase.<>c__DisplayClass30_0.b__4(IBinding binding)
[xUnit.net 00:00:01.1415982] at System.Linq.Enumerable.WhereSelectListIterator2.MoveNext() [xUnit.net 00:00:01.1417209] at System.Linq.Enumerable.<CastIterator>d__351.MoveNext()
[xUnit.net 00:00:01.1418372] at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source, Int32& length) [xUnit.net 00:00:01.1419433] at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source)
[xUnit.net 00:00:01.1420609] at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) [xUnit.net 00:00:01.1675591] Ninject.Extensions.Factory.FactoryTests.SingleBinding [FAIL] [xUnit.net 00:00:01.1677361] Ninject.ActivationException : Error activating IInterceptor using conditional implicit self-binding of IInterceptor [xUnit.net 00:00:01.1678101] Provider returned null. [xUnit.net 00:00:01.1678507] Activation path: [xUnit.net 00:00:01.1678918] 2) Injection of dependency IInterceptor into parameter of constructor of type IWeaponFactoryProxy [xUnit.net 00:00:01.1679713] 1) Request for IWeaponFactory [xUnit.net 00:00:01.1680517] [xUnit.net 00:00:01.1681176] Suggestions: [xUnit.net 00:00:01.1681877] 1) Ensure that the provider handles creation requests properly. [xUnit.net 00:00:01.1682377] [xUnit.net 00:00:01.1683019] Stack Trace: [xUnit.net 00:00:01.1684114] c:\projects\git\Ninject\!Ninject 3.2.3 NetCore Working\Ninject\Activation\Context.cs(186,0): at Ninject.Activation.Context.ResolveInternal(Object scope) [xUnit.net 00:00:01.1686055] c:\projects\git\Ninject\!Ninject 3.2.3 NetCore Working\Ninject\Activation\Context.cs(160,0): at Ninject.Activation.Context.Resolve() [xUnit.net 00:00:01.1687210] c:\projects\git\Ninject\!Ninject 3.2.3 NetCore Working\Ninject\KernelBase.cs(400,0): at Ninject.KernelBase.<>c__DisplayClass30_0.<Resolve>b__4(IBinding binding) [xUnit.net 00:00:01.1688993] at System.Linq.Enumerable.WhereSelectListIterator2.MoveNext()
[xUnit.net 00:00:01.1689989] at System.Linq.Enumerable.d__351.MoveNext() [xUnit.net 00:00:01.1691058] at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source, Int32& length)
[xUnit.net 00:00:01.1691738] at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source) [xUnit.net 00:00:01.1692786] at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source)
[xUnit.net 00:00:01.1734806] Finished: Ninject.Extensions.Factory.Test
Test failed

Ninject and its plugins is complicated so I am unable to fix this issue by myself. Please help.

Visual Studio Code solution here: https://www.dropbox.com/s/gi3jf0facgzlgvv/Example.zip?dl=0
I am using VS Code 1.12.2 on Windows. VS code extensions:

  • C# for Visual Studio Code (powered by OmniSharp)
  • Nuget package manager

Target framework is netcoreapp1.1.

PTR:

  1. Open the solution in VS Code
  2. Press Ctrl+` to open terminal
  3. Execute
    dotnet restore .\Ninject.Extensions.Factory.Test\Ninject.Extensions.Factory.Test.csproj
    dotnet build .\Ninject.Extensions.Factory.Test\Ninject.Extensions.Factory.Test.csproj
  4. open FactoryTests.cs file, find SingleBinding test and press "run test" nearby the test's name
    OR
    execute
    dotnet test .\Ninject.Extensions.Factory.Test\Ninject.Extensions.Factory.Test.csproj
    to run all tests. There are 43 failed test at all (120 total).

Any help/ideas/suggestions?

Performance problem

I want to use your Factory extension so I profiled your project and found several inefficient code places changing which could really improve performance:

1/ FuncProvider.Create should cache result of

functionFactory.GetMethodInfo(genericArguments.Length).MakeGenericMethod(genericArguments) 

with static ConcurrentDictionary or alternatives.

2/ FuncProvider.Create should use cached Reflection.Emit-ed method to do Invoke instead of plain reflection.

3/ FunctionFactory.GetMethodInfo should cache its results.

Nuget package installs incompatible version of Castle.Core

Ninject Factory requires Castle.Core 3.2 due to missing .NET45 support in previous versions, but Package configuration for Ninject Factory defines 3.0.0 as the minimally required version.

Workaround:
Update Castle.Core manually.

Fix:
Update minimally required version of castle core in package definition

Factory with generic method throws ActivationException

If a factory interface has a generic method it throws ActivationException when you try to create dependency by this method.

    public interface IRecieverFactory
    {
        IReciever<TData> Get<TData>();
    }

    kernel.Bind<IRecieverFactory>().ToFactory()

StandardInstanceProvider resolves it to named binding with empty name.
I solved this problem by overriding GetName:

    public class GenericFactoryMethodInstanceProvider : StandardInstanceProvider
    {
        protected override string GetName(MethodInfo methodInfo, object[] arguments)
        {
            return null;
        }
    }
    kernel.Bind<IRecieverFactory>().ToFactory(() => new GenericFactoryMethodInstanceProvider());

This is a bug I think.

Emphazise Lazy<T> instance reuse in documention

I know this is a case of rtfm but I just had an hour long debugging session and would suggest to highlight the following in the documentation of the Lazy section.

This lazy-created instance will then be reused for all subsequent accesses to .Value.

Provide easier opt-out for Func<> binding

Hi Remo
How about splitting the FuncModule into a FactoryModule (everything except .Bind(typeof(Func<...)) and a FuncFactoryModule?
This would allow for easier opt-out from Func<..>. The open Func<....> binding may hide issues with bindings when one wants to bind specific Func<MyFoo, MyBar>().

See http://stackoverflow.com/questions/24862138/stop-ninject-from-binding-funct-t-bool-automatically/24863850.

One could further provide an extension like

IBindingRoot.Bind<Func<MyFoo, MyBar>().ToFuncFactory();

or just

IBindingRoot.Bind<Func<MyFoo, MyBar>().ToFactory();

to simplify binding specific factories.

Please tell me whether you like the idea - in which case i'll happily provide pull request - or not.

EDIT: this is a duplicate of #21

Injecting runtime configuration

My problem:

public class RuntimeConfiguration
{
    public int Number { get; set; }
}

public class DependencyOfDependency
{
    public DependencyOfDependency(RuntimeConfiguration test)
    {
        Console.WriteLine(test.Number);
    }
}

public class Dependency
{
    public Dependency(DependencyOfDependency d) { }
}

public interface IDependencyFactory
{
    Dependency Create(RuntimeConfiguration configuration);
}

var kernel = new StandardKernel(new FuncModule());
kernel.Bind<Dependency>().ToSelf();
kernel.Bind<DependencyOfDependency>().ToSelf();
kernel.Bind<IDependencyFactory>().ToFactory();
kernel.Get<IDependencyFactory>().Create(new RuntimeConfiguration { Number = 42 });

It prints 0 instead of 42.

My solution:

public class DependencyFactory : IDependencyFactory
{
    private readonly IKernel kernel;

    public DependencyFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public Dependency Create(RuntimeConfiguration configuration)
    {
        lock (kernel)
        {
            kernel.Bind<RuntimeConfiguration>().ToConstant(configuration);

            var result = kernel.Get<Dependency>();

            kernel.Unbind<RuntimeConfiguration>();

            return result;
        }
    }
}

kernel.Bind<IDependencyFactory>().To<DependencyFactory>();

Problems with this approach:

(1) It feels like an unnecessary hack.
(2) Possible performance issues due to locking.

I can't figure out a better solution though. Any advice?

Can this project reference be updated

Since this is being used by Ninject.Extensions.Conventions alot of .dll can be loaded dynamically, and it seems that it ignores binding-redirects and causes the wrong verison of ninject to be loaded.

I was wondering if a version can be made with updates references to the newer ninject?

Thank you.

Extension does not compile with latest Ninject version from master

The issue is that in the private method ToFactory in BindToExtensions syntax.Kernel is accessed. IBindingToSyntax<T> does not have the member Kernel (I guess that was removed during the ReadOnlyKernel refactoring?).

Is there any other way to access the current IBindingRoot in that method?

IConstructorArgument not found during build

I tried to build the extension, but the build was failed bacouse IConstructorArgument was not found. What should be done to solve this problem?

Beg a pardon if I'm doing something wrong. Quite new here.

New NuGet release?

Hi,

I have problems with Lazy in .NET Core, which is fixed by #42 as far as I can see (which we currently have a fix that replaces the LazyConstructorScorer with a copy of the one in #42)

Is there any plans to push a new release out with the latest code? Is there anything I can do to help out to make that happen?

Can't find Lazy type

I'm interested in using the lazy functionality, but there isn't a lazy type, is it?

.Net Core2: Ninject.Extensions.Factory.FuncTests.LazyInjection fails

Several constructors have the same priority.

Ninject.Extensions.Factory.FuncTests.LazyInjection
Error message:
 Ninject.ActivationException : Error activating Lazy{IWeapon} using implicit self-binding of Lazy{IWeapon}
Several constructors have the same priority. Please specify the constructor using ToConstructor syntax or add an Inject attribute.

Constructors:
Lazy`1(IWeapon value)
Lazy`1(Func{IWeapon} valueFactory)

Activation path:
  2) Injection of dependency Lazy{IWeapon} into parameter lazyWeapon of constructor of type ClassWithLazy
  1) Request for ClassWithLazy

Suggestions:
  1) Ensure that the implementation type has a public constructor.
  2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.

ะขั€ะฐััะธั€ะพะฒะบะฐ ัั‚ะตะบะฐ:
   at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.SingleOrThrowException[T](IEnumerable`1 series, Func`1 exceptionCreator)
   at Ninject.Activation.Providers.StandardProvider.DetermineConstructorInjectionDirective(IContext context)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
   at Ninject.Activation.Context.ResolveInternal(Object scope)
   at Ninject.Activation.Context.Resolve()
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.KernelBase.Resolve(IRequest request)
   at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
   at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
   at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass15_0.<Create>b__0(ITarget target)
   at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
   at Ninject.Activation.Context.ResolveInternal(Object scope)
   at Ninject.Activation.Context.Resolve()
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.KernelBase.Resolve(IRequest request)
   at Ninject.ResolutionExtensions.GetResolutionIterator(IResolutionRoot root, Type service, Func`2 constraint, IEnumerable`1 parameters, Boolean isOptional, Boolean isUnique)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
   at Ninject.Extensions.Factory.FuncTests.LazyInjection() 

Take a look on results of this snippet:

            var t = typeof(Lazy<IWeapon>);
            var cs = t.GetConstructors();

            foreach(var c in cs)
            {
                Console.WriteLine(c.ToString());
            }

.Net Framework:

Void .ctor()
Void .ctor(System.Func`1[ConsoleApplication37.IWeapon])
Void .ctor(Boolean)
Void .ctor(System.Threading.LazyThreadSafetyMode)
Void .ctor(System.Func`1[ConsoleApplication37.IWeapon], Boolean)
Void .ctor(System.Func`1[ConsoleApplication37.IWeapon], System.Threading.LazyThreadSafetyMode)

Total: 6

.Net Core:

Void .ctor()
Void .ctor(ConsoleApplication37.IWeapon)
Void .ctor(System.Func`1[ConsoleApplication37.IWeapon])
Void .ctor(Boolean)
Void .ctor(System.Threading.LazyThreadSafetyMode)
Void .ctor(System.Func`1[ConsoleApplication37.IWeapon], Boolean)
Void .ctor(System.Func`1[ConsoleApplication37.IWeapon], System.Threading.LazyThreadSafetyMode)

Total: 7
Extra constructor: Void .ctor(ConsoleApplication37.IWeapon)

Cannot Resolve with AllowNullInjection = true

Problem: Ninject allows for null injection if a sutible match cannot be found. Factories do not. Instead and ActivationException is thrown.

Test showing the failure.

    [TestFixture]
    public class AllowNullInjectionTests
    {
        private StandardKernel _kernal;

        [SetUp]
        public void Initialize()
        {
            _kernal = new StandardKernel(new NinjectSettings()
            {
                AllowNullInjection = true
            });
            _kernal.Load(new TestModule());
        }

        [Test]
        public void NullInjection()
        {
            _kernal.Should().Resolve<SomeTestClass>();
        }

        //This Test Fails
        [Test]
        public void NullInjectionInFactory()
        {
            var testClass = _kernal.Get<ITestClassFactory>().GetTestClass();
            testClass.Should().NotBeNull();
        }
    }

    public class TestModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ITestClass>().To<SomeTestClass>();
            Bind<ITestClassFactory>().ToFactory();
        }
    }

    public interface ITestClassFactory
    {
        ITestClass GetTestClass();
    }

    public class SomeTestClass : ITestClass
    {
        private readonly IDependency _dependency;

        public SomeTestClass(IDependency dependency = null)
        {
            _dependency = dependency;
        }
    }

    public interface IDependency
    {

    }

    public interface ITestClass
    {
    }

Doesn't work with .net core 2.0

I have:

  • Ninject 3.3.3
  • Ninject.Extensions.Factory 3.3.2

I have converted a working project from .net 4.6.1 to .net standard 2.0 and .net core 2.0. Now none of my Ninject.Extensions.Factory stuff works.

The Func<> automatic bindings are not happening, I get a runtime error saying it couldnt' find a binding for Func (I have worked around this be automatically binding all the Func<T's> that I need.

The interface factories like the following:
Bind<IWorkerThreadFactory>().ToFactory();

Result in a runtime error as follows:

System.NotImplementedException: 'This is a DynamicProxy2 error: There are no interceptors specified for method 'Tait.EnableFleet.Agent.FlowControl.IWorkerThread CreateWorkerThread(System.String)' which has no target. When calling method without target there is no implementation to 'proceed' to and it is the responsibility of the interceptor to mimic the implementation (set return value, out arguments etc)'

I have triple checked that my projects are using Ninject.Extensions.Factory 3.3.2 via nuget.

Small issue(?) with NamedLikeFactoryMethod

Hi! I have a small issue with my simple example.

I have simple factory interface:

  public interface ICameraFactory
    {
       ICameraController GetNikonCamera();
       ICameraController GetCanonCamera();
    }

I bind it as a factory:

  IKernel kernel = new StandardKernel();
  kernel.Bind<ICameraFactory>().ToFactory();

When i try to convert:

kernel.Bind<ICameraController>().To<NikonCameraController>().Named("NikonCamera");

to:

kernel.Bind<ICameraController>().To<NikonCameraController>().NamedLikeFactoryMethod<ICameraFactory>(f => f.GetNikonCamera());

it's don't compile.

For example, this code is compiled (but it's terrible):

kernel.Bind<ICameraController>().ToMethod<ICameraController>(c=>new NikonCameraController()).NamedLikeFactoryMethod<ICameraController, ICameraFactory>(f => f.GetNikonCamera());

What am I doing wrong?
Ninject 3.0.1.10
Ninject.Extension.Factory 3.0.1.0

Current implementation is a service-locator, which is an anti-pattern

The entire idea of DI is to resolve all dependencies once at the app root, however current implementation of this factory extension violates that principle by resolving the object being produced by a factory and its dependencies on demand. This can lead to unexpected behavior at runtime instead of fail-fast at the startup. Such problem does not occur when you implement a factory by hand, because the compiler will do the compile-time checks.

Here is an example:

public interface IFooFactory
{
    IFoo Create();
}

class Foo : IFoo
{
    public Foo(IBar bar) { ... }
}

static void Main()
{
    // Create bindings, but forget about IFoo and IBar
    var kernel = new StandardKernel();
    kernel.Bind<IFooFactory>().ToFactory();
    // Resolve dependency graph at startup
    var factory = kernel.Get<IFooFactory>();
    // Somewhere down the stream: Oops! IFoo or one of its dependencies is not bound :(
    var foo = factory.Create();
}

Those dependency checks should be done when a factory is instantiated.

Make compatible with NInject 4 (especially with .NET Native)

When this is installed with NInject 4 beta, and built on a UWP project in Release mode (thus invoking the .NET Native compiler), the following build error occurs:

NUTC3059:Failed to find member with name 'GetBindings' and signature '20 1 15 12 80 ad 1 12 79 12 21' in type 'Ninject.IKernel' while resolving token 'a00003a' from module 'Ninject.Extensions.Factory' while compiling method 'instance System.Void Ninject.Extensions.Factory.FuncModule.Load()'.

It would be great if this extension supported current (if prerelease) versions of NInject

Castle.Core 3.2

Upgrading to Castle.Core 3.2 is not possible with the current extension version. Make it compatible

Handling for parameter name mismatches

If a factory interface's parameter names don't match the constructor arguments for the constructed type, you get an exception message that looks like this:

Ninject.ActivationException was unhandled by user code
  Message=Error activating <parameter type>
No matching bindings are available, and the type is not self-bindable.
Activation path:
  2) Injection of dependency <parameter type> into parameter <constructor argument name> of constructor of type <factory-created type>
  1) Request for <factory-created type>

Suggestions:
  1) Ensure that you have defined a binding for <parameter type>.
  2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
  3) Ensure you have not accidentally created more than one kernel.
  4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.

It's attempting to resolve the parameter from the container instead of passing the parameter through. Either of these would be fantastic:

  1. Add rudimentary handling for mismatched parameter names so that if the types are compatible, names don't have to match
  2. Provide better exception messaging, along the lines of "Unable to resolve parameter named in constructor parameter of type "

Help for a use case

Hello,
i have a similar situation.
I was forced to create a IPerformer interface with parametrized methods because MyClass works with Ninject and i can't add more parameters other than bound interface to kernel.
My goal is to remove parameters to IPerformer methods and pass in some way to Myclass.
Factory could be the solution, but i can't figure how to do it.
Can someone drop me some lines of code, please?

public Interface IPerformer
{
	void Perform_A(int id, string name);
	void Perform_B(int id, string name);
	void Perform_C(int id, string name);
}


public MyClass : IPerformer
{
	private readonly IMapper _mapper;
	private readonly IManager _manager;

	public MyClass(IMapper mapper, IManager manager)
	{
		_mapper = mapper;
		_manager = manager;
	}

	public void Perform_A(int id, string name)
	{ 
		_manager.DoSomething_A(id, name);
	}

	public void Perform_B(int id, string name)
	{
		_manager.DoSomething_B(id, name);
	}

	public void Perform_C(int id, string name)
	{
		_manager.DoSomething_C(id, name);
	}
}

StackOverflow reference: My StackOverflow post

Thanks
Max

this module doesnt seem to be compatible when WCF Extensions or MVC3 extensions are in use

I am trying to use the Factory extensions in the same project that uses MVC3 extensions and WCF Extensions. My test is synonymous with the "CustomInstanceProviderTest" in file "src/Ninject.Extensions.Factory.Test/FactoryTests.cs".

I have downloaded all of the latest 2.3 builds from the build server and I am referencing these compiled assemblies in my test project.

When I run my unit tests where ONLY Ninject and the Factory extensions are referenced, then all is well and works as expected. However, when I continue adding the other Extensions and Ninject Dependencies to support WCF and MVC then things start to fail.

This is the error that is output at test time...
"Test 'NinjectFactoryExtension.FactoryTests.TransactionManagerIsCreated' failed: System.MissingMethodException : Method not found: 'Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax1<!!0> Ninject.Syntax.IBindingToSyntax1.To()'.
at Ninject.Extensions.Wcf.WcfModule.Load()
at Ninject.Modules.NinjectModule.OnLoad(IKernel kernel)
at Ninject.KernelBase.Load(IEnumerable1 m) at Ninject.KernelBase.Load(IEnumerable1 assemblies)
at Ninject.Modules.CompiledModuleLoaderPlugin.LoadModules(IEnumerable1 filenames) at Ninject.Modules.ModuleLoader.LoadModules(IEnumerable1 patterns)
at Ninject.KernelBase.Load(IEnumerable`1 filePatterns)
at Ninject.KernelBase..ctor(IComponentContainer components, INinjectSettings settings, INinjectModule[] modules)
at Ninject.KernelBase..ctor(INinjectModule[] modules)
at Ninject.StandardKernel..ctor(INinjectModule[] modules)
Class1.cs(19,0): at NinjectFactoryExtension.FactoryTests.TransactionManagerIsCreated()"

Steps to repro...

Create a unit test project
Add references to the following...

  • Ninject 2.3.0.67 (the version that is in the lib folder with Ninject.Extensions.Factory)
  • Ninject.Extensions.Factory 2.3.0.11
  • Ninject.Extensions.WCF 2.3.0.22
  • Ninject.Web.Common 2.3.0.18

There is an alternate scenario, that produces another error. When you add a reference to Ninject.Web.MVC from build artifact "Ninject.Web.Mvc3-2.3.0.18-release-net-4.0" then you end up with the following error:

"Test 'NinjectFactoryExtension.FactoryTests.TransactionManagerIsCreated' failed: System.TypeLoadException : Could not load type 'Ninject.Infrastructure.IHaveBindingConfiguration' from assembly 'Ninject, Version=2.3.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7'.
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()
at Ninject.Infrastructure.Language.ExtensionsForAssembly.HasNinjectModules(Assembly assembly)
at Ninject.Modules.CompiledModuleLoaderPlugin.b__0(Assembly asm)
at Ninject.Modules.AssemblyNameRetriever.AssemblyChecker.GetAssemblyNames(IEnumerable1 filenames, Predicate1 filter)
at Ninject.Modules.AssemblyNameRetriever.AssemblyChecker.GetAssemblyNames(IEnumerable1 filenames, Predicate1 filter)
at Ninject.Modules.AssemblyNameRetriever.GetAssemblyNames(IEnumerable1 filenames, Predicate1 filter)
at Ninject.Modules.CompiledModuleLoaderPlugin.LoadModules(IEnumerable1 filenames) at Ninject.Modules.ModuleLoader.LoadModules(IEnumerable1 patterns)
at Ninject.KernelBase.Load(IEnumerable`1 filePatterns)
at Ninject.KernelBase..ctor(IComponentContainer components, INinjectSettings settings, INinjectModule[] modules)
at Ninject.KernelBase..ctor(INinjectModule[] modules)
at Ninject.StandardKernel..ctor(INinjectModule[] modules)
Class1.cs(19,0): at NinjectFactoryExtension.FactoryTests.TransactionManagerIsCreated()"

Castle.Core 3.3 dependency

We use Castle.Core 3.3.0.0 in our project.

TestStack.White-0.13.3 uses Castle.Core 3.3.0.0
Ninject.Extensions.Factory-3.2.1.0 uses Castle.Core 3.2.0.0
Ninject.Extensions.Interception.DynamicProxy-3.2.0.0 uses Castle.Core 3.2.0.0

Now we get a warning MSB3247 - Found conflicts between different versions of the same dependent assembly.

I think the problem is that Ninject.Extensions.Factory andNinject.Extensions.Interception.DynamicProxy does reference Castle.Core 3.2.0.0 (which has strong name. But then the nuget-dependecies is a little bit useless when VS/MSBuild have problem with this.

One workaround I've found is to use BindingRedirects but this should not be neccesary in my opinion.

Factory is matching argument names in dependent constructors and causing InvalidCastException

In the following example, the factory tries to construct an instance of Class2 passing the argument "argumentA" of type IClass1 passed to the factory method to Class2's constructor instead of using the binding rule to create an instance of Class3. This throws an invalid cast exception.

If I change the name of the constructor argument of Class2 to "ArgumentB" the code works.

Ninject.Extension.Factory v3.3.2
Ninject v3.3.4

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject;
using Ninject.Extensions.Factory;

namespace ConsoleApp19
{
    class Program
    {
        static void Main(string[] args)
        {
            var kernel = new StandardKernel();
            kernel.Bind<IClass1>().To<Class1>();
            kernel.Bind<IClass2>().To<Class2>();
            kernel.Bind<IClass3>().To<Class3>();
            kernel.Bind<IClass4>().To<Class4>();
            kernel.Bind<IClass4Factory>().ToFactory();

            var factory = kernel.Get<IClass4Factory>();
            var class1 = kernel.Get<IClass1>();

            // fails with exception Unable to cast object of type 'ConsoleApp19.Class1' to type 'ConsoleApp19.IClass3'
            var class4 = factory.CreateInstance(class1);
        }
    }

    public interface IClass1
    {

    }
    public class Class1 : IClass1
    {
    }

    public interface IClass2
    {

    }
    public class Class2 : IClass2
    {
        public Class2(IClass3 argumentA)
        {

        }
    }

    public interface IClass3
    {

    }

    public class Class3 : IClass3
    {

    }

    public interface IClass4
    {

    }

    public interface IClass4Factory
    {
        IClass4 CreateInstance(IClass1 argumentA);
    }

    public class Class4 : IClass4
    {
        public Class4(IClass1 argumentA, IClass2 class2)
        {

        }
    }
}

Silverlight 3.0 is not supported

Hi,

just wanted to let you guys know your library doesn't support silverlight 3.0 since 2012 (commit 9859017) because of Castle.Core losing support for the platform.
It would be nice to not have it look like the platform is supported. The commit I referenced renamed the SL4 Castle.Core libs to be the SL3, which obviously doesn't work.

ToFactory should take in the implementation type

With current design an end user must bind both a factory interface to a factory and the result interface to a concrete type:

kernel.Bind<IFooFactory>().ToFactory();
kernel.Bind<IFoo>().To<Foo>();

This creates a danger (actually have happened) of ability to inject IFoo directly bypassing the factory just because its interface binding is required for the factory to work.
Ideally, in such cases the extension method should be ToFactoryOf<Foo>() or ToFactory().Of<Foo>() which allows explicitly specify the implementation type without a necessity to bind it.

Error when injecting `Func<IEnumerable<T>>`

(Not sure if this is a bug in Ninject itself or in the factory extension)

In the following example BusinessLogic gets the factories for MySqlDb and SqliteDb but not for MsSqlDb. MsSqlDb is bound using WhenInjectedInto<T>, but still it should work, shouldn't it?

public class NinjectTest
{
    [Fact]
    public void ShouldLazilyCreateObjects()
    {
        var kernel = new StandardKernel();
        kernel.Bind<BusinessLogic>().ToSelf();
        kernel.Bind<IDb>().To<MsSqlDb>().WhenInjectedInto<BusinessLogic>().InTransientScope();
        kernel.Bind<IDb>().To<MySqlDb>().InTransientScope();
        kernel.Bind<IDb>().To<SqliteDb>().InTransientScope();
        var bl = kernel.Get<BusinessLogic>();
        Assert.Equal(3, bl.DbFactories().Count());
    }
}

public interface IDb { }
public class SqliteDb : IDb { }
public class MySqlDb : IDb { }
public class MsSqlDb : IDb {  }

public class BusinessLogic
{
    public IEnumerable<Func<IDb>> DbFactories { get; }

    public BusinessLogic(IEnumerable<Func<IDb>> dbFactories)
    {
        DbFactories = dbFactories;
    }
}

I also tried injecting it as IEnumerable<Func<IDb>> but that gets me only one Func and invoking that fails with an ActivationException that there are too many bindings:

An exception of type 'Ninject.ActivationException' occurred in Ninject.dll but was not handled in user code

Additional information: Error activating IDb

More than one matching bindings are available.

Matching bindings:

  1) binding from IDb to MySqlDb

  2) binding from IDb to SqliteDb

Activation path:

  1) Request for IDb



Suggestions:

  1) Ensure that you have defined a binding for IDb only once.

Ninject.Extensions.Factory not passing factory interface to class constructor

Hello,

I followed your example in the Extensions.Factory documentation. I created a factory interface. My main class has a constructor with the factory interface as a parameter. I bind the factory interface in the NinjectWebCommon.cs that was created for me when I added references to Web.Common and Extensions.Factory. But my main class' constructor with the factory interface parameter is not called.

Who can I contact for help?

Factory and Interception

The problem appears to be an interaction or failure to interact between Ninject.Extensions.Interception and Ninject.Extensions.Factory. They work separately, but if you create an object using Factory interface and it is annotated with a C# attribute to proxy the constructed object with a proxy interceptor, it fails with an error:

2019-07-23T22:22:27.3407669Z Failed   SanityTest
2019-07-23T22:22:27.3418793Z Error Message:
2019-07-23T22:22:27.3419112Z  Initialization method MyDevice.Test.SmokeTest.TestInitialize threw exception. System.NotImplementedException: This is a DynamicProxy2 error: There are no interceptors specified for method 'ModelNameSpace.SetOfModels.ModelObject CreateModelObject()' which has no target. When calling method without target there is no implementation to 'proceed' to and it is the responsibility of the interceptor to mimic the implementation (set return value, out arguments etc).
2019-07-23T22:22:27.3419440Z Stack Trace:
2019-07-23T22:22:27.3419618Z     at Castle.DynamicProxy.AbstractInvocation.ThrowOnNoTarget()
2019-07-23T22:22:27.3419713Z    at Castle.DynamicProxy.Internal.CompositionInvocation.EnsureValidTarget()
2019-07-23T22:22:27.3419823Z    at Castle.Proxies.Invocations.IModelFactory_CreateModelObject.InvokeMethodOnTarget()
2019-07-23T22:22:27.3420072Z    at Castle.DynamicProxy.AbstractInvocation.Proceed()
2019-07-23T22:22:27.3420161Z    at Castle.Proxies.IModelFactoryProxy.CreateModelObject()
2019-07-23T22:22:27.3420473Z    at MyDevice.ConfigurationFactory.MyDeviceControl..ctor(IModelFactory ModelFactory, String dutUri) in D:\Agent_1\_work\8\s\TestToolbox\MyDevice\ConfigurationFactory\MyDeviceControl.cs:line 85
2019-07-23T22:22:27.3421003Z    at MyDevice.Test.SmokeTest.TestInitialize() in D:\Agent_1\_work\8\s\TestToolbox\MyDevice.Test\SmokeTest.cs:line 90
2019-07-23T22:22:27.3421220Z 
2019-07-23T22:22:27.3429234Z Standard Output Messages:
2019-07-23T22:22:27.3429441Z  Creating a new T-Rex Helper for URI: 'http://10.15.128.54:32011'
2019-07-23T22:22:27.3429606Z  Setting the Helper timeout to 120000 milliseconds. 

Is there some syntactic sugar to make this work? Or is this a bug? Or as yet unimplemented feature?

This is cross posted to the Interception project. It may be a team effort :), and based on the responses, I would be glad to fork and take a SWAG at it if code changes are needed..

Add support for async factory methods

We use the Ninject factory extensions in a project that I'm working on and we have come across the need in some cases for async instantiation which has come into conflict with some of the auto-implemented factory goodness we have been enjoying.

The basic concept is to allow the factory extensions to work with methods (func or auto-implemented interface method contracts) that return a result of Task.

public class MyClass
{
   public MyClass(int nonServiceDependency, IMyService serviceDependency)
   {
      ...
   }
}

public class IMyClassFactory
{
   public async Task<MyClass> CreateMyClassAsync(int nonServiceDependency);
}

And usage would look something like.

kernel.Bind<IMyClassFactory>().ToFactory();

var factory = kernel.Get<IMyClassFactory>();
var instanceFromFactory = await factory.CreateMyClassAsync(42);

// or alternatively

var func = kernel.Get<Func<int, Task<MyClass>>>();
var instanceFromFunc = await func(42);

Naming an interface method "Get..." leads to unexpected behavior

See this Stackoverflow post.

When the method is named "GetSomethingSomething" it leads to an Ninject.ActivationException - presumably because the ConstructorArgument is missing.

When you rename the method to Create or Make everything works fine.

This is due to the feature described here:

The default instace provider of the extension has the convention that it tries to return an instance using a named binding whenever a method starts with โ€œGetโ€. E.g. IFoo GetMySpecialFoo() is equal to
resolutionRoot.Get<IFoo>("MySpecialFoo");

However, the ActivationException does not give this as a hint. For a new user it is very hard to find out why it doesn't work and what he has got to do.

Longer term, i would suggest that this feature would be redesigned. One could, for example, put an attribute on the method like:

public interface IFooFactory
{
    [Named("A")]
    CreateFooA();

   [Named("B")]
   CreateFooB();
}

or pass it as a parameter:

public interface IFooFactory
{
    CreateFoo([NamedBinding] string name);
 }

Does not work under Compact Framework?

Hello,

It seems that the "ToFactory( )" extension methods is not part of the factory dll.
Is there a way to use the factory under compact framework 3.5?

Best regards.
Loic

Factory extension silently binds Func<...>

In our code, we had a really weird bug related to Ninject, and according to this stackoverflow answer, the root cause was that the Ninject Factory extension bind Func<T,T,bool> (and possibly other Funcs).

Assume an object such as

public class PriorityQueue<T>(Func<T,T,bool> cmp_func) : IPriorityQueue<T>
{ ... } 

and a Factory

public IPriorityQueueFactory 
{
    IPriorityQueue<T> Create<T>();
} 

The expected behavior would be that Ninject will throw an exception, because the constructor argument was not bound. But this will not happen; instead, the factory extension will silently inject the non-user-bound Func<...>.

This is very confusing, and it cost me a long time to track down the bug.

I would assume that for most users, silently adding bindings for something as common as a Func<...> is outside of the expected behavior of a ninject extension.

The problem gets even worse if using custom factories as explained here. Then the bug occurs if the factory extension is in the usings, but behaves correctly otherwise.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.