根据这篇文章,一个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",但是编译它不是必需的.是否有编译,我的意思是引人注目,有理由,让我先加上"私人只读"?
由于此处没有相关文档(官方文档仅讨论使用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
一次,一次为每个请求创建的范围.
你必须使用依赖注入(structuremap,ninject).如果你不想使用DI,那么你必须提供一个重载构造函数,如下所示
public DuckbillsController():this( new DuckbillRepository()) { }
控制器工厂为您创建它们......您需要查看依赖注入.
尝试Autofac,它与MVC有很好的集成.