Coder Social home page Coder Social logo

ninject.web.webapi'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.web.webapi's People

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  avatar  avatar  avatar  avatar  avatar

Watchers

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

ninject.web.webapi's Issues

Ninject 3.3.1

Hi,

We are upgrading to Ninject 3.3.1 and other ninject extensions.
Is it possible to have a build with the latest ninject version components and dependencies for this library?

thanks

BindHttpFilter called twice, not only when IFilterBindingInNamedWithOrOnSyntax condition is true

I have these bindings in NinjectModule:

this.Bind<IBar>().ToMethod(ctx => new Bar()).WhenTargetHas<BarAttribute>();
this.Bind<IBar>().ToMethod(ctx => new Bar2());

When I inject IBar, Ninject correctly injects new Bar() when there's BarAttribute and
injects new Bar2() without BarAttribute.

For instance,

public class BarController
{
   public BarController([Bar]IBar bar) {} // injects new Bar()
}
public class Bar2Controller
{
   public Bar2Controller(IBar bar) {} // injects new Bar2()
}

But using BindHttpFilter, this "chain" behavior is different..

this.BindHttpFilter<FooAttribute>(FilterScope.Action)
   .WhenActionMethodHas<AllowAnonymousAttribute>()
   .WithConstructorArgument("foo", (object)null);
this.BindHttpFilter<FooAttribute>(FilterScope.Action);

public class FooController
{
   [AllowAnonymous]
   public Method() {}
}

public class FooAttribute : AuthorizeAttribute
{
   public FooAttribute(IDependency dependency) {}
}

When I request /foo/method, Ninject calls FooAttribute twice and injects null (using first binding) as expected, then instantiates FooAttribute again with IDependency binding.

What I expected was Ninject.Webapi chain the conditions and solve at the first match, as it does with normal Bind<>.

To solve my need (inject some paremeter when action is decorated with [AllowAnonymous], and another parameter when action isn't decorated with [AllowAnonymous]), I need to create mutual exclusive conditions which is a bad to maintain these two behaviors with Ninject Bind<> and Ninject.Web.WebApi BindHttpFilter<>:

this.BindHttpFilter<FooAttribute>(FilterScope.Action)
   .WhenActionMethodHas<AllowAnonymousAttribute>()
   .WithConstructorArgument("foo", (object)null);
this.BindHttpFilter<FooAttribute>(FilterScope.Action)
   .When((httpConfig, actionDescriptor) => !actionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())

What do you think ?

OWIN and InRequestScope

The Owin-SampleApplication application has the following controller...

public class ValuesController : ApiController
{
    private readonly IValuesProvider valuesProvider1;
    private readonly IValuesProvider valuesProvider2;

    /// <summary>
    /// Initializes a new instance of the <see cref="ValuesController"/> class.
    /// </summary>
    /// <param name="valuesProvider">The values provider.</param>
    public ValuesController(IValuesProvider valuesProvider1, IValuesProvider valuesProvider2)
    {
        this.valuesProvider1 = valuesProvider1;
        this.valuesProvider2 = valuesProvider2;
    }

    /// <summary>
    /// Handles: GET /values
    /// </summary>
    /// <returns>The values</returns>
    public IEnumerable<string> Get()
    {
        return this.valuesProvider1.GetValues().Union(this.valuesProvider2.GetValues());
    }
}

The output from the Get() is..

[
  "Value1",
  "Value2",
  "Value3",
  "Value4",
  "Value5",
  "Value6"
]

...which is expected as IValuesProvider is injected with the InRequestScope.

If you add the following controller...

public class Values2Controller : ApiController
{
    private readonly IValuesProvider valuesProvider1;
    private readonly IValuesProvider valuesProvider2;

    /// <summary>
    /// Initializes a new instance of the <see cref="ValuesController"/> class.
    /// </summary>
    /// <param name="valuesProvider">The values provider.</param>
    public Values2Controller(IKernel kernel)
    {
        this.valuesProvider1 = kernel.Get<IValuesProvider>();
        this.valuesProvider2 = kernel.Get<IValuesProvider>();
    }

    /// <summary>
    /// Handles: GET /values
    /// </summary>
    /// <returns>The values</returns>
    public IEnumerable<string> Get()
    {
        return this.valuesProvider1.GetValues().Union(this.valuesProvider2.GetValues());
    }
}

The output is ...
[
"Value1",
"Value2",
"Value3"
]
...which is not expected. In Values2Controller two instances of IValuesProvider are created despite the InRequestScope Syntax.

Incorrect implementation for WebApi with Owin (do not use this extension for the time being!)

The extension has severe bugs when it comes to dealing with Owin. I would strongly recommend everyone to stay away from this until these bugs have been fixed.

The OwinNinjectDependencyResolver creates a named scope but it never uses it for resolving via HttpConfiguration.DependencyResolver. It's not proxying the calls to the proper resolution root, and it fails silently in OwinWebApiRequestScopeProvider with an UnknownScopeException, returning a NULL request scope. InRequestScope instances resolved like this will behave as transient and will not be cleaned up!

The implementation is also incompatible with Owin middleware pipeline. The Ninject.Web.Common.OwinHost creates a scope for this purpose inside OwinBootstrapper, however this extension completely ignores it. When attempting to resolve services inside middlewares, it behaves exactly the same as described above, failing silently and creating transient instances instead.

In a nutshell, the extension fails to properly cope with an Owin request scope. Using it can have severe consequences leading to unexpected situations which are very hard to detect and solve. I can't stress enough. This extension is NOT ready for prime time!

InRequestmode doesn't work

I created a project with EF6 + Ninject + Owin. I realized that Ninject InRequestScope doesn't work, infact, in a single Web Api request the constructor of my DBContext derived class fires more than once.

The Startup file of my web api project is like:

public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);

app.UseNinjectMiddleware(CreateKernel).UseNinjectWebApi(config);

}

private static IKernel CreateKernel()
{
// I have my Ninject module in a separate assembly
var kernel = new StandardKernel(new Core.Ioc.AutoBotMapper());

GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

return kernel;

}
My Module:

public class AutoBotMapper : NinjectModule
{
private readonly ILog _logger = LogManager.GetLogger("CORE");

public override void Load()
{
    // Contesto is my DBContext
    Bind<Contesto>().ToSelf().InRequestScope(); 

    // Other Binds
    Bind<ITournamentServiceFactory>().ToFactory();
    Bind<ITournamentCloser>().To<TournamentCloser>();

    ...
}

}

Could not load type 'Ninject.Web.WebApi.IWebApiRequestScopeProvider' from assembly 'Ninject.Web.WebApi, Version=3.3.1.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7'.

We have a OWIN-selfhosted Web API in a Service Fabric cluster. Version 3.3.0 starts without problems. Upgrading to version 3.3.1 gives the error:

Could not load type 'Ninject.Web.WebApi.IWebApiRequestScopeProvider' from assembly 'Ninject.Web.WebApi, Version=3.3.1.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7'.

The code for the program.cs of the service fabric service:

private static void Main()
        {
            try
            {
                using (var healthReporter = new FabricHealthReporter())
                {
                    using (var listener = new ApplicationInsightsEventListener(healthReporter))
                    {
                        TelemetryConfiguration.Active.InstrumentationKey = ConfigurationManager.AppSettings["ApplicationInsightsKey"];

                        using (IKernel kernel = new StandardKernel())
                        {
                            var modules = new List<INinjectModule>
                            {
                                new AzureSearchModule()
                            };
                            kernel.Load(modules);

                            kernel.Bind<IServiceFactory>().To<ServiceFactory>().InSingletonScope();
                            kernel.Bind<IAsfaltAanvraagSearchClient>().To<AsfaltAanvraagSearchClient>().InSingletonScope();
                            kernel.Bind<IAsfaltProductiePlanningSearchClient>().To<AsfaltProductiePlanningSearchClient>().InSingletonScope();
                            kernel.Bind<IPlanbordEventsRepository>().To<PlanbordEventsRepository>().InTransientScope();
                            kernel.Bind<IProjectdossierEventsRepository>().To<ProjectdossierEventsRepository>().InTransientScope();

                            // The ServiceManifest.XML file defines one or more service type names.
                            // Registering a service maps a service type name to a .NET type.
                            // When Service Fabric creates an instance of this service type,
                            // an instance of the class is created in this host process.
                            ServiceRuntime.RegisterServiceAsync(
                                "ServiceFabricApiType",
                                context => new ServiceFabricApi(
                                    context,
                                    kernel.Get<IAsfaltProductiePlanningSearchClient>(),
                                    kernel.Get<IAsfaltAanvraagSearchClient>(),
                                    kernel.Get<IPlanbordEventsRepository>(),
                                    kernel.Get<IProjectdossierEventsRepository>(),
                                    kernel.Get<IServiceFactory>()))
                                .GetAwaiter()
                                .GetResult();

                            using (var process = Process.GetCurrentProcess())
                            {
                                ServiceEventSource.Current.ServiceTypeRegistered(process.Id, typeof(ServiceFabricApi).Name);

                                // Prevents this host process from terminating so services keep running.
                                Thread.Sleep(Timeout.Infinite);
                                GC.KeepAlive(listener);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ServiceEventSource.Current.ServiceHostInitializationFailed(string.Format("ServiceFabricApi.Main ERROR: {0}", ExceptionHelper.GetExceptionLogMessage(ex)));
                throw;
            }

As said, version 3.3.0 works fine with this code. What are we missing?

update Microsoft.AspNet.WebApi to 5.2.3 then the DI not work!

{"Message":"出现错误。","ExceptionMessage":"尝试创建“UsersController”类型的控制器时出错。请确保控制器具有无参数公共构造函数。","ExceptionType":"System.InvalidOperationException","StackTrace":" 在 System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n 在 System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n 在 System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","InnerException":{"Message":"出现错误。","ExceptionMessage":"类型“Account.Api.Controllers.UsersController”没有默认构造函数","ExceptionType":"System.ArgumentException","StackTrace":" 在 System.Linq.Expressions.Expression.New(Type type)\r\n 在 System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n 在 System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n 在 System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"}}

An error occurred when trying to create a controller of type...

I installed Ninject Web API 3.2.4 (which is the current version on NuGet Manager) in a new Web API MVC 5 project. After adding and modifying the NinjectWebCommon.cs file in the App_start folder I tried to run some queries using postman. However I keep receiving this error:

screen shot 2015-03-17 at 20 30 42

When I downgrade to Ninject Web API 3.2.3, I don't get the error and everything works fine.

I looks like there are some breaking changes in the new version or is there a new way to configure Ninject Web API 3.2.4?

Owin + WebApi - Ninject 'Provider' does not work honor request scope

When using a Ninject Provider<T> (factory) to create a dependency, the dependencies resolved from the IContext passed to the Provider will not honor any 'Per Request' scoping.

When in Owin/WebApi world, ninject creates a named scope per request which is automatically bound to a context but it seems that the context passed to the CreateInstance method is somehow not aware of any global named scope.

To reproduce, create a provider which relies on some per request object:

public class FooProvider : Provider<IFoo>
{
    protected override IFoo CreateInstance(IContext context)
    {
        var bar = context.Kernel.Get<IBar>(); // This should call the Bar constructor
        var bar2 = context.Kernel.Get<IBar>(); // This should return the same instance but is calling the constructor again

        return new Foo(bar, bar2);
    }
}

Registration:

Bind<IBar>().To<Bar>().InRequestScope();
Bind<IFoo>().ToProvider<FooProvider>();

Now you would need a WebApi controller hosted in Owin to rely on an IFoo.

NotImplementedException when WebApi is used with NInject

The problem can be easy to reproduce by creating a new MVC+WebAPI project via the standard ASP.NET project template, adding the required Owin and the Ninject packages, removing the setup logic in the global.asax.cs, creating a Startup class as the one below:

using Microsoft.Owin;
using UrlHelperWebApiTests;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Owin;
using Ninject.Web.WebApi.OwinHost;


[assembly: OwinStartup(typeof(Startup))]
namespace UrlHelperWebApiTests
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configure(
                config =>
                {
                    AreaRegistration.RegisterAllAreas();
                    WebApiConfig.Register(config);
                    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                    RouteConfig.RegisterRoutes(RouteTable.Routes);
                    BundleConfig.RegisterBundles(BundleTable.Bundles);

                    app.UseNinjectMiddleware(() => new StandardKernel()).UseNinjectWebApi(config);
                });
        }
    }
}

and by changing the default GET of the ValuesController to:

        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" }.Select(id=> this.Url.Link("DefaultApi",new{controller="Values",id=id})).ToArray();
        }

When UseNinjectWebApi is active in the Startup, the GET will fail with a NotImplementedException.

When UseNinjectWebApi is not active, the GET will succeed. This is because HostedHttpRouteCollection.GetVirtualPath is looking for the HTTP context in the property bag of the request. This is set up by the HttpControllerHandler which attaches the context to the MS_HttpContext key.

Nuget package Ninject.Web.WebApi.WebHost: Error activating HttpConfiguration v3.2.4

Hello,

It looks like the nuget package for Ninject.Web.WebApi.Host v3.2.4 has a dependency on Ninject.Web.WebApi with a range of (>= 3.2.0 && < 3.3.0). But, when I let nuget pull in v3.2.0 of .WebApi I get the Ninject.ActivationException described in this stackoverflow post.

If I update the .WebApi nuget reference to v3.2.4, then the exception no longer occurs.

I was wondering if it's possible to update Ninject.Web.WebApi.Host v3.2.4's nuget package to have a minimum version range of v3.2.4 on .WebApi?

Ninject.Web.WebApi NuGet Dependencies

The NuGet package Ninject.Web.WebApi depends upon Microsoft.AspNet.WebApi which pulls in Microsoft.AspNet.WebApi.WebHost and Microsoft.AspNet.WebApi.Core. Unfortunately this means that if you pull in Ninject.Web.WebApi.Owin you also pull in a bunch of unnecessary dependencies for IIS hosting.

I think Ninject.Web.WebApi should probably be dependent on Microsoft.AspNet.WebApi.Core instead.

Self/Owin Hosting InRequestScope broken without ContextPreservation extension,

I'm currently writing integration tests for my ASP.NET Web API.

In the Web API project, we are using Ninject.Web.WebApi.WebHost and InRequestScope works great.

In our integration test project, we are using ASP.NET WebAPI in-memory testing, passing a Ninject bootstrapped HttpSelfHostConfiguration to an HttpServer:

`

	private static string _url = "http://localhost:12345/";

	private static HttpSelfHostConfiguration Config { get; set; }

	static WebApi()
	{
		Config = new HttpSelfHostConfiguration(_url);
		WebApiConfig.Register(Config);

		Config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

		var selfHost = new NinjectSelfHostBootstrapper(CreateKernel, Config);
	}

	public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
	{
		var client = new HttpClient(new HttpServer(Config));

		HttpResponseMessage response;

		try
		{
			response = await client.SendAsync(request, new CancellationTokenSource().Token);
		}
		catch (HttpResponseException ex)
		{
			response = ex.Response;
		}

		return response;
	}

	private static IKernel CreateKernel()
	{
		var kernel = NinjectWebCommon.CreateKernel();

		return kernel;
	}

`
We are using Entity Framework and binding the DbContext in the request scope:

public ContractsController(IContractBL contractBL) { this._BusinessLayer = contractBL; }

this.Bind<IContractBL>().To<ContractBL>().Intercept().With<IDataLayerInterceptor>();
this.Bind<IContractRepo>().To<ContractRepo>().Intercept().With<IIntegrationLayerInterceptor>();
this.Bind<PartnerContext>().ToSelf().InRequestScope();

`

When I do not have the ContextPreservation extension installed, the SelfHostWebApiRequestScopeProvider.GetRequestScope throws an UnknownScopeException.

I see that both Owin and Self-Host both use NamedScope under the covers to do the request scoping. Should ContextPreservation be added as a dependency to these solutions?

Also, as an aside, would the named scoping solution work for WebHosting? If so, could the RequestScope code be pulled down into Ninject.Web.WebApi and allow all hosting solutions to leverage the same code?

HttpFilters not being injected.

In 3.2.4, the .BindHttpFilter<IFilter> method works fine, however the filter is never instantiated or injected.

Recreate:

  1. Create a Filter attribute (e.g. an action filter, as in the examples)
  2. In a NinjectConfigurator (or wherever your configurations are done), bind the filter w/ the syntax, putting it in whatever scope you'd like:
    container.BindHttpFilter<LogActionFilter>( FilterScope.Controller );
  3. Add breakpoints to the Filter's constructor or other methods
  4. Run the project
  5. Hit a controller (e.g. "api/customers"). Notice that the constructor is never called.

Downgrade to 3.2.2, repeat steps above, notice constructor is called.

I ran a diff between 3.2.2 and 3.2.4, and apparently the offending line is this one:

this.Bind<HttpConfiguration>( ).ToMethod( ctx => GlobalConfiguration.Configuration );

Proof:

  1. Recreate problem with 3.2.4 per steps above
  2. As the very first thing you bind (before binding filters), add this:
    container.Bind<HttpConfiguration>( ).ToMethod( ctx => GlobalConfiguration.Configuration );
  3. Repeat steps, notice constructor is now called.

Not sure why the bind to HttpConfiguration was removed, but it apparently broke HttpFilter injection.

The name 'GlobalConfiguration' does not exist in the current context

Hi,

After updating Ninject.Web.WebApi to version 3.2.4.0, I get this compiler error:

The name 'GlobalConfiguration' does not exist in the current context.

And it's pointing to this line GlobalConfiguration.Configure(WebApiConfig.Register); in the global.asax.cs file.
Something wrong with the references/dependencies?

Edit:
I rolled back to the previous stable version and that works.

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.