我正在寻找Web Api 2,Owin和Autofac,需要一些指导。
概述
我有一个Owin自托管的Web Api,它使用Autofac进行IoC和依赖注入。该项目是一个控制台应用程序,就像一个服务,这意味着它可以停止和启动。我有一个带有两个构造函数的身份验证控制器:一个参数少,另一个注入存储库。
问题
当我运行服务并调用api时,我的无参数构造函数被调用,我的存储库永远不会被注入(_repository = null)。
研究
我已经做了一些研究,并在Github上发现了一些有用的项目,我将其复制到了发球台,但我错过了很大一部分难题。 This很有帮助,但没有解决我的问题。我在Stack Overflow上阅读this question,Dane Sparza有一个很好的demo project,但我找不到明确的解决方案。问题不在于自托管,而在于依赖注入。
我的代码(为了解释而细化)
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
var connectioninfo = ConnectionInfo.FromAppConfig("mongodb");
var builder = new ContainerBuilder(); // Create the container builder.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // Register the Web API controllers.
builder.Register(c => new Logger()).As<ILogger>().InstancePerRequest(); // Register a logger service to be used by the controller and middleware.
builder.RegisterType<AuthenticationRepository>().As<IAuthenticationRepository>().WithParameter(new NamedParameter("connectionInfo", connectioninfo)).InstancePerRequest();
var container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container); // Create an assign a dependency resolver for Web API to use.
GlobalConfiguration.Configuration.DependencyResolver = resolver; // Configure Web API with the dependency resolver
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
app.UseAutofacWebApi(config); // Make sure the Autofac lifetime scope is passed to Web API.
}
Program.cs的
static void Main(string[] args)
{
var service = new ApiService(typeof(Program), args);
var baseAddress = "http://localhost:9000/";
IDisposable _server = null;
service.Run(
delegate()
{
_server = WebApp.Start<Startup>(url: baseAddress);
},
delegate()
{
if (_server != null)
{
_server.Dispose();
}
}
);
}
ApiController
public class AuthenticationController : ApiController
{
private IAuthenticationRepository _repository;
public AuthenticationController() { }
public AuthenticationController(IAuthenticationRepository repository)
{
_repository = repository;
}
[AllowAnonymous]
public IHttpActionResult Authenticate(string name, string password)
{
if (_repository == null)
return BadRequest("User repository is null.");
var valid = _repository.AuthenticateUser(name, password);
return Ok(valid);
}
}
答案 0 :(得分:37)
你应该使用HttpConfiguration
,你到处都是OWIN引导。
所以,这个:
GlobalConfiguration.Configuration.DependencyResolver = resolver;
应该成为:
config.DependencyResolver = resolver;
除此之外,一切看起来都不错。 Api控制器已注册,但您没有给它们一个范围。不确定在Autofac范围内是否默认为每个请求控制器,或者它是否具有每个请求范围的概念(我知道LightInject有它)。
环顾四周,我认为您遵循Autofac的Google Code repo上的示例,它确实使用了GlobalConfiguration。相反,如果你看一下GitHub example,它会有所不同。尝试根据此进行更改。包括这个:
// This should be the first middleware added to the IAppBuilder.
app.UseAutofacMiddleware(container);
2016年更新
我上面所说的内容仍然适用,但Autofac的文档中提供了额外的内容(感谢Brad):
OWIN集成中的常见错误是使用 GlobalConfiguration.Configuration。在OWIN你创建了 从头开始配置。你不应该参考 使用OWIN时的GlobalConfiguration.Configuration 集成。