español - web api rest c#
Enlace web ASP.NET API con ninject (11)
¿Has registrado el contenedor con el frawework? Prefiero usar autofac, aquí hay un ejemplo de cómo usar autofac con API. http://alexmg.com/post/2012/03/08/Autofac-ASPNET-Web-API-%28Beta%29-Integration.aspx
Además, Mark Seeman tiene una buena publicación sobre DI en general con WebAPI
http://blog.ploeh.dk/2012/03/20/RobustDIWithTheASPNETWebAPI.aspx
De Ploeh:
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
t => this.container.Kernel.HasComponent(t) ?
this.container.Resolve(t) :
null,
t => this.container.ResolveAll(t).Cast<object>());
Lo anterior debe realizarse en el archivo global.asax
Acabo de instalar la actualización mcc4 rc y estoy intentando crear una aplicación api con poca suerte.
Estoy usando ninject pero no puedo cargar mis controladores. Sigo recibiendo un error
Escriba ''Api.Controllers.ConsumerController'' no tiene un constructor predeterminado
Soy muy nuevo en mvc y uso de inyección así que por favor tengan paciencia conmigo.
No he hecho nada especial para el enlace predeterminado que se crea a través de nuget
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IConsumerRepository>().To<ConsumerRepository>();
}
}
Mi controlador parece
private readonly IConsumerRepository _repository;
public ConsumerController(IConsumerRepository repository)
{
_repository = repository;
}
[HttpGet]
public IQueryable<Consumer> Get(Guid id)
{
return _repository.Get(id).AsQueryable();
}
¿Qué debo hacer para que los controladores api funcionen con ninject?
Lo siento si esto es simple
Intenté su sugerencia Michael sin embargo después de cambiar el webcommon.cs a este
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IConsumerRepository>().To<ConsumerRepository>();
}
Me sale un error cuando
var kernel = new StandardKernel();
se llama
El método ''GetFilters'' en el tipo ''Ninject.Web.WebApi.Filter.DefaultFilterProvider'' del ensamblado ''Ninject.Web.WebApi, Versión = 3.0.0.0, Cultura = neutral, PublicKeyToken = c7192dc5380945e7'' no tiene una implementación.
¿Qué me estoy perdiendo?
Espero que esto ayude a alguien más ...
Yo estaba teniendo el mismo problema y estaba relacionado con el movimiento de la clase responsable de registrar el ensamblaje a cargo de la inicialización de los controladores. Movido fuera de la web en el proyecto de marco.
Usar Autofac pero lo mismo se aplicaría a otros contenedores.
Estaba llamando:
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
Lo cual funciona bien cuando está dentro de la aplicación web, pero arrojó la excepción anterior cuando se movió al proyecto del marco ya que el ensamblaje en ejecución ya no contiene los controladores.
En cambio, tuvo que actualizar a:
builder.RegisterApiControllers(Assembly.GetCallingAssembly());
Este mensaje de error genérico
Escriba ''Api.Controllers.ConsumerController'' no tiene un constructor predeterminado
también puede ocurrir si no hace que su constructor sea público, o la dependencia no puede ser resuelta por el contenedor IoC debido a la falta de un argumento.
El mensaje de error es engañoso para decir lo menos.
Le pregunté a Brad Wilson sobre esto y ha cambiado en MVC4 RC.
GlobalConfiguration.Configuration.ServiceResolver ha sido movido a GlobalConfiguration.Configuration.DependencyResolver
Utilice esta implementación para crear un Ninject DependencyResolver para su API web: https://gist.github.com/2417226
En NinjectWebCommon.cs :
// Register Dependencies
RegisterServices(kernel);
// Set Web API Resolver
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
Para alguien que aterriza aquí mientras busca ''... no tiene un constructor predeterminado'' que busque una forma fácil de depurar configuraciones que fallan silenciosamente:
- Eliminar los objetos inyectados por el constructor hasta que se pueda invocar el constructor
- Para cada uno de los objetos previamente inyectados, ahora no inicializados, invoque usando:
ServiceLocator.Current.GetInstance<[OBJ-TYPE]>()
El objeto ofensivo causará una ActivationException con un mensaje descriptivo. Tendrás que buscar algo.
Recuerde eliminar la llamada a la reparación posterior de ServiceLocator. Es decir. esta no es una recomendación para utilizar el patrón de localización de servicios fuera de la depuración.
Parece que Ninject no arrojó una excepción, como generalmente ocurre cuando las dependencias de IOC no están configuradas correctamente. En cambio, parecía que no había registrado el resolvedor de dependencias WebAPI, lo que sin duda hice. Aquí estaba mi solución a este problema, pero por lo que he encontrado podría ser MUCHOS tipos diferentes de problemas de configuración. Simplemente vuelve a verificar todo en la cadena de dependencia. ¡Espero que ayude a alguien!
El controlador:
public class ContestsController : ApiController
{
//Ninject wouldn''t inject this CTOR argument resulting in the error
public ContestsController(IContestEntryService contestEntryService)
{
La dependencia:
public class ContestEntryService : IContestEntryService
{
public ContestEntryService(IContestsContext contestsContext)
{
La configuración incorrecta:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IContestsContext>()
.To<ContestsContext>()
.InRequestScope();
kernel.Bind(x =>
x.FromAssembliesMatching("MyNameSpace.*")
.SelectAllClasses()
.BindAllInterfaces()
);
La configuración correcta:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(x =>
x.FromAssembliesMatching("MyNameSpace.*")
.SelectAllClasses()
.BindAllInterfaces()
);
kernel.ReBind<IContestsContext>()
.To<ContestsContext>()
.InRequestScope();
En general, Ninject es bastante bueno a la hora de informar este tipo de errores, ¡así que realmente me interesaron por este!
Puede instalar el paquete NuGet WebApiContrib.IoC.Ninject y agregar la siguiente línea de código a NinjectWebCommon.cs
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
Sé que es una publicación anterior, pero encontré la solución en algún enlace para compartirla aquí. Espero eso ayude.
También recibí este mensaje de error, pero resultó que una de mis interfaces en realidad no fue implementada por ninguna clase (se me olvidó agregarla a la declaración de la clase).
si alguien todavía tiene problemas, por favor escucha por alguna razón que ninject no funciona como esperaríamos con mvc 4. En tu API web, necesitas escribir este código
public DefaultController() : base() { }
Esto elimina el error al decir que no hay un constructor predeterminado, luego cuando necesitas obtener tus datos del método get escribe este código:
public IEnumerable<YourModelGoesHere> Get()
{
return context.YourData;
}
Tenga en cuenta que también tendrá que acceder a su clase de db aquí, por ejemplo:
DefaultConnection context = new DefaultConnection();
solo instale el paquete Ninject.MvcXXX, donde XXX - versión de MVC ...