Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Web API控制器&x27;谁的构造函数被调用了?_C#_Asp.net Web Api_Controller_Ioc Container_Constructor Injection - Fatal编程技术网

C# Web API控制器&x27;谁的构造函数被调用了?

C# Web API控制器&x27;谁的构造函数被调用了?,c#,asp.net-web-api,controller,ioc-container,constructor-injection,C#,Asp.net Web Api,Controller,Ioc Container,Constructor Injection,根据,控制器应该有一个构造函数,该构造函数将要实现的接口传入,la: public class DuckbillsController : ApiController { IDuckbillRepository _platypiRepository; public DuckbillsController(IDuckbillRepository platypiRepository) { if (platypiRepository == null)

根据,控制器应该有一个构造函数,该构造函数将要实现的接口传入,la:

public class DuckbillsController : ApiController
{
    IDuckbillRepository _platypiRepository;

    public DuckbillsController(IDuckbillRepository platypiRepository)
    {
        if (platypiRepository == null)
        {
            throw new ArgumentNullException("platypiRepository is null");
        }
        _platypiRepository = platypiRepository;
    }
}
但是这个构造函数是如何调用的呢?通过调用此类中包含的Web API方法的客户端进行计算,但如何传递接口类型?或者这不一定要发生(任何人/任何地方都没有显式调用构造函数)

更新
规范示例显示接口声明前面有“private readonly”,但编译时不需要这样做。我的意思是说,有没有一个令人信服的理由让我在“private readonly”前面加上前缀?

你必须使用依赖注入(structuremap,ninject)什么的。如果您不想使用DI,那么必须提供如下所示的重载构造函数

public DuckbillsController():this( new DuckbillRepository())
{
}

控制器工厂为您创建它们。。。您需要了解依赖项注入


试试Autofac,它对MVC有一个很好的集成。

因为在任何地方都没有关于这个的文档(官方文档只是讨论与Unity进行集成)。这是你怎么做的

HttpConfiguration.DependencyResolver
属性是
IDependecyResolver
的一个实例,它基本上是一个服务定位器(您请求类型的实例,它知道如何创建它)。我想要的是提供我自己的控制器实例化

像这样使用:

config.DependencyResolver = 
   new OverriddenWebApiDependencyResolver(config.DependencyResolver)
   .Add(typeof(ScoreboardController), () => 
                                    new ScoreboardController(Messages) 
   ); 
这样实施:

/// <summary>
/// The standard web api dependency resolver cannot inject dependencies into a controller 
/// use this as a simple makeshift IoC
/// </summary>
public class OverriddenWebApiDependencyResolver : WebApiOverrideDependency<IDependencyResolver >, IDependencyResolver {
    public OverriddenWebApiDependencyResolver Add(Type serviceType, Func<object> initializer) {
        provided.Add(serviceType, initializer);
        return this;
    }
    public IDependencyScope BeginScope() => new Scope(inner.BeginScope(), provided);
    public OverriddenWebApiDependencyResolver(IDependencyResolver inner) : base(inner, new Dictionary<Type, Func<object>>()) { }
    public class Scope : WebApiOverrideDependency<IDependencyScope>, IDependencyScope {
        public Scope(IDependencyScope inner, IDictionary<Type, Func<object>> provided) : base(inner, provided) { }
    }
}
public abstract class WebApiOverrideDependency<T> : IDependencyScope where T : IDependencyScope {
    public void Dispose() => inner.Dispose();
    public Object GetService(Type serviceType) {
        Func<Object> res;
        return provided.TryGetValue(serviceType, out res) ? res() : inner.GetService(serviceType);
    }

    public IEnumerable<Object> GetServices(Type serviceType) {
        Func<Object> res;
        return inner.GetServices(serviceType).Concat(provided.TryGetValue(serviceType, out res) ? new[] { res()} : Enumerable.Empty<object>());
    }
    protected readonly T inner;
    protected readonly IDictionary<Type, Func<object>> provided;
    public WebApiOverrideDependency(T inner, IDictionary<Type, Func<object>> provided) {
        this.inner = inner;
        this.provided = provided;
    }

}
//
///标准web api依赖项解析器无法将依赖项注入控制器
///把它当作一个简单的权宜之计
/// 
公共类OverridedWebAPIDependencyResolver:WebApiOverrideDependency,IDependencyResolver{
公共重写WebAPI依赖解析程序添加(类型serviceType,Func初始值设定项){
提供.添加(服务类型,初始值设定项);
归还这个;
}
public idependencycoscope BeginScope()=>新范围(提供了inner.BeginScope());
public-overridedWebAPIDependencyResolver(IDependencyResolver-inner):基(inner,new Dictionary()){}
公共类作用域:WebapiOverridedDependence、IDependencyScope{
公共作用域(IDependencyScope内部,提供IDictionary):基(内部,提供){}
}
}
公共抽象类WebApiOverridedDependence:IDependencyScope,其中T:IDependencyScope{
public void Dispose()=>internal.Dispose();
公共对象GetService(类型serviceType){
Func res;
返回提供的.TryGetValue(serviceType,out res)?res():inner.GetService(serviceType);
}
公共IEnumerable GetServices(类型serviceType){
Func res;
返回inner.GetServices(serviceType).Concat(提供的.TryGetValue(serviceType,out res)?new[]{res()}:Enumerable.Empty());
}
受保护的只读T内部;
提供受保护的只读词典;
公共WebApiOverrideDependence(T内部,提供IDictionary){
this.inner=内部;
这是提供的;
}
}

诀窍是您实际上必须实现两次
IDependencyScope
,一次用于
idependencysolver
,一次用于它在每个请求中创建的范围。

这应该是将DI引入类中;这就是我添加构造函数及其参数的原因。那么还需要什么呢?我们使用的是Castle Windsor。Castle Windsor支持MVC,这是为DI添加的;我们使用的是Windsor Castle。一般来说,没有编写代码来显式调用构造函数。您需要将DI容器挂钩到WebApi框架中,容器将使用反射来实例化控制器。可能有助于解释问题。这实际上是一个非常合理的问题,提供的答案只是说“看看这个(第三方工具)”。令人悲哀的事实是,微软在记录这些方面做得非常糟糕,不幸的是,回答这些问题的责任落在了社区身上;如果我没有标记另一个作为答案,我会选择这个。你可以随时更改它:)但没什么大不了的。只是为了子孙后代才放在这里