Web Api 2、Owin、およびAutofacに足を踏み入れたので、ガイダンスが必要です。
概要
IoCおよび依存性注入にAutofacを使用するOwinセルフホストWeb Apiがあります。プロジェクトは、サービスのように動作するコンソールアプリです。つまり、停止および開始できます。 2つのコンストラクターを持つ認証コントローラーがあります。1つはパラメーターなし、もう1つはリポジトリーを挿入します。
問題
サービスを実行してapiを呼び出すと、パラメーターのないコンストラクターが呼び出され、リポジトリーが挿入されません(_repository = null)。
研究
かなりの調査を行ったところ、Githubで役立つプロジェクトが見つかりました。これをティーに複製しましたが、パズルの大部分が欠落しています。 これ は役に立ちましたが、私の問題は解決しませんでした。 Stack Overflowで この質問 を読み、Dane SparzaにはNice デモプロジェクト がありましたが、明確な解決策が見つかりませんでした。問題は、セルフホスティングではなく、依存性注入です。
マイコード(説明のために間引かれています)
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);
}
}
どこでもOWINをブートストラップするHttpConfiguration
を使用する必要があります。したがって、この:
GlobalConfiguration.Configuration.DependencyResolver = resolver;
になるはずです:
config.DependencyResolver = resolver;
それ以外は、すべてがよさそうだ。 APIコントローラーは登録されていますが、スコープを与えていません。 Autofacスコープのデフォルトがコントローラーのリクエストごとのスコープであるかどうか、またはリクエストごとのスコープの概念があるかどうかはわかりません(LightInjectが持っていることは知っています)。
周りを見てみると、実際にGlobalConfigurationを使用しているAutofacのGoogle Codeリポジトリの例に従っていると思います。代わりに、 GitHubの例 を見ると、少し異なります。これに従って変更を行ってください。これを含む:
// This should be the first middleware added to the IAppBuilder.
app.UseAutofacMiddleware(container);
2016 update
上で言ったことはまだ当てはまりますが、Autofacのドキュメントから余分なものがあります(ブラッドに感謝)
OWIN統合の一般的なエラーは、GlobalConfiguration.Configurationの使用です。 OWINでは、構成を最初から作成します。 OWIN統合を使用する場合、GlobalConfiguration.Configurationを参照しないでください。