我是否需要注册 autofac 容器来连接 webapps 依赖解析器?
Do I need to register autofac's container with itself to wire up webapi's depdendency resolver?
我正在使用 Topshelf 编写一个 Windows 服务,它应该启动一个自托管的 webapi 项目和一个基于 quickfix/n 的 FIX 服务。请考虑下面的缩短代码,到目前为止它仍然有效。
但是有一个问题 - 现在我的应用程序中存在两个容器实例。我的直觉告诉我这是个坏主意,尤其是因为我正在加载 MyBigModule
两次。也因为我的控制器之一需要与使用 quickfix 的控制器相同的组件。
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
// Assembly B
public class WebHost : IWebHost
{
// ...
public void Start()
{
WebApp.Start<Startup>("someUrl");
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
我的第一个方法是将 Action<IAppBuilder>
传递给在 Main()
中创建的 WebHost
构造函数。像这样:
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyBigModule>();
var container = builder.Build();
var webhost = new WebHost("someUrl", app =>
{
var config = new HttpConfiguration();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ....
});
builder.RegisterInstance(webost);
// ...
}
}
但是我必须先构建我的容器,然后再添加另一个注册。这不符合容器应被视为不可变的建议。另一种替代方法是将容器实例向下传递到我的 WebHost
s Startup
class。
看来我需要在容器本身内注册我的容器。我该怎么做?也许有更好的方法?我希望很清楚我在挣扎什么。
我很确定一定有更好的方法来连接 webapi 的解析器。非常感谢任何想法和反馈。
我同时解决了它,感谢。我们可以将 ILifetimeScope
的实例注入构造函数而无需注册任何东西。
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class WebHost : IWebHost
{
private readoly ILifetimeScope scope
public WebHost(ILifetimeScope scope)
{
this.scope = scope;
}
public void Start()
{
WebApp.Start("someUri", app => {
var config = new HttpConfiguration
{
DependencyResolver = new AutofacWebApiDependencyResolver(this.scope)
};
// ...
});
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
我正在使用 Topshelf 编写一个 Windows 服务,它应该启动一个自托管的 webapi 项目和一个基于 quickfix/n 的 FIX 服务。请考虑下面的缩短代码,到目前为止它仍然有效。
但是有一个问题 - 现在我的应用程序中存在两个容器实例。我的直觉告诉我这是个坏主意,尤其是因为我正在加载 MyBigModule
两次。也因为我的控制器之一需要与使用 quickfix 的控制器相同的组件。
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
// Assembly B
public class WebHost : IWebHost
{
// ...
public void Start()
{
WebApp.Start<Startup>("someUrl");
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
我的第一个方法是将 Action<IAppBuilder>
传递给在 Main()
中创建的 WebHost
构造函数。像这样:
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyBigModule>();
var container = builder.Build();
var webhost = new WebHost("someUrl", app =>
{
var config = new HttpConfiguration();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ....
});
builder.RegisterInstance(webost);
// ...
}
}
但是我必须先构建我的容器,然后再添加另一个注册。这不符合容器应被视为不可变的建议。另一种替代方法是将容器实例向下传递到我的 WebHost
s Startup
class。
看来我需要在容器本身内注册我的容器。我该怎么做?也许有更好的方法?我希望很清楚我在挣扎什么。
我很确定一定有更好的方法来连接 webapi 的解析器。非常感谢任何想法和反馈。
我同时解决了它,感谢ILifetimeScope
的实例注入构造函数而无需注册任何东西。
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class WebHost : IWebHost
{
private readoly ILifetimeScope scope
public WebHost(ILifetimeScope scope)
{
this.scope = scope;
}
public void Start()
{
WebApp.Start("someUri", app => {
var config = new HttpConfiguration
{
DependencyResolver = new AutofacWebApiDependencyResolver(this.scope)
};
// ...
});
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}