根据this article,一个Controller应该有一个构造函数来获取要传入的接口,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”,但编译时不需要这样做。是否有一个编译,我的意思是引人注目,理由,让我在“私人只读”前加上?
答案 0 :(得分:11)
由于此处没有相关文档(官方文档仅讨论使用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;
}
}
诀窍在于,您实际上必须实施IDependencyScope
两次 - 一次用于IDependencyResolver
,一次用于为每个请求创建的范围。
答案 1 :(得分:7)
控制器工厂为您创建它们......您需要查看依赖注入。
尝试使用Autofac,它与MVC有很好的集成。
答案 2 :(得分:6)
你必须使用依赖注入(structuremap,ninject)。如果你不想使用DI,那么你必须提供一个重载构造函数,如下所示
public DuckbillsController():this( new DuckbillRepository())
{
}