Asp.net mvc 5 在MVC5控制器中使用StructureMap[4.7.0]Setter注入
我正在尝试将Asp.net mvc 5 在MVC5控制器中使用StructureMap[4.7.0]Setter注入,asp.net-mvc-5,inversion-of-control,structuremap,structuremap4,setter-injection,Asp.net Mvc 5,Inversion Of Control,Structuremap,Structuremap4,Setter Injection,我正在尝试将iaapplicationconfigurationsection实现注入这个MVC5控制器,这样我就可以从我所有视图中的web.config自定义部分访问一些信息(各种字符串): public class BaseController : Controller { public IApplicationConfigurationSection AppConfig { get; set; } public BaseController() {
iaapplicationconfigurationsection
实现注入这个MVC5控制器
,这样我就可以从我所有视图中的web.config
自定义部分访问一些信息(各种字符串):
public class BaseController : Controller
{
public IApplicationConfigurationSection AppConfig { get; set; }
public BaseController()
{
ViewBag.AppConfig = AppConfig; // AppConfig is always null
}
}
我想使用setter注入,这样我就不必把派生的控制器构造函数与它们并不真正关心的参数混在一起
注意:如果有更好的方法注入基类依赖项,请告诉我。我承认我在这方面可能走得不对
在myGlobal.asax
中,我加载我的StructureMap配置:
private static IContainer _container;
protected void Application_Start()
{
_container = new Container();
StructureMapConfig.Configure(_container, () => Container ?? _container);
// redacted other registrations
}
MyStructureMappConfig
类加载我的注册表:
public class StructureMapConfig
{
public static void Configure(IContainer container, Func<IContainer> func)
{
DependencyResolver.SetResolver(new StructureMapDependencyResolver(func));
container.Configure(cfg =>
{
cfg.AddRegistries(new Registry[]
{
new MvcRegistry(),
// other registries redacted
});
});
}
}
这会起作用,但没有
我发现,如果我放弃setter注入而使用构造函数注入,它就会像广告中那样工作。我仍然想知道我错在哪里,但我想强调的是,我不是StructureMap大师-可能有更好的方法避免构造函数注入我的基类依赖项。如果你知道我应该怎么做,但我不是,请分享 而在这种情况下,构造函数注入似乎是解决所述问题的更好方法,如下所示
方法和类应该明确地要求(通常通过方法参数或构造函数参数)它们需要的任何协作对象才能正常工作
在您的视图中提到只需要访问AppConfig
,这让我觉得这更像是一个跨领域的问题
控制器本身似乎不需要使用依赖项,因此不需要显式地将它们注入控制器,以便视图可以使用依赖项
考虑使用一个动作过滤器,该过滤器可以解决依赖关系,并在请求通过管道时通过相同的ViewBag
使视图可以使用该过滤器
公共类访问应用程序配置属性:ActionFilterAttribute{
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext){
var resolver=DependencyResolver.Current;
var appConfig=(iaapplicationconfigurationsection)resolver.GetService(typeof(iaapplicationconfigurationsection));
filterContext.Controller.ViewBag.AppConfig=AppConfig;
}
}
现在,这使得视图可以使用所需的信息,而不需要使用控制器的紧密耦合。不再需要将依赖项注入派生类
通过使用过滤器属性修饰控制器/操作
[AccessAppConfig]//可用于其所有操作
公共类HomeController:控制器{
//[AccessAppConfig]//如果要隔离到单个操作/视图,请直接使用
公共行动结果索引(){
//...
返回视图();
}
}
或全局用于所有请求
公共类过滤器配置{
公共静态无效注册表全局过滤器(全局过滤器集合过滤器){
添加(新的accessAppConfigAttribute());
}
}
在这一点上,使用哪个IoC容器并不重要。一旦配置了依赖项解析程序,视图应该可以访问ViewBag
中所需的信息,构造函数注入是更好的方法。我本来打算回答这个问题的,但刚刚看到你的更新说明你已经做到了。其次,我认为ViewBag
只填充了一个动作,这与您在构造函数中给出的示例不同。在一个完全不同的注释中,我刚刚读到StructureMap已被屏蔽。
ViewBag很容易从构造函数访问。我还没有听说过StructureMap,我得看看是否能找到链接。好的,我在访问ViewBag的构造函数上得到了更正。至于日落,它位于框架的主要位置(…)[非常好的解决方案。与控制器分离非常聪明。现在还不能授予奖金,但它是你的。@ScottBaker很乐意提供帮助。@ScottBaker在Asp.Net Core中期待的一件很酷的事情是视图允许强类型依赖项注入。ie@InjectiaApplicationConfiguration部分AppConfig
参考
public class MvcRegistry : Registry
{
public MvcRegistry()
{
For<BundleCollection>().Use(BundleTable.Bundles);
For<RouteCollection>().Use(RouteTable.Routes);
For<IPrincipal>().Use(() => HttpContext.Current.User);
For<IIdentity>().Use(() => HttpContext.Current.User.Identity);
For<ICurrentUser>().Use<CurrentUser>();
For<HttpSessionStateBase>()
.Use(() => new HttpSessionStateWrapper(HttpContext.Current.Session));
For<HttpContextBase>()
.Use(() => new HttpContextWrapper(HttpContext.Current));
For<HttpServerUtilityBase>()
.Use(() => new HttpServerUtilityWrapper(HttpContext.Current.Server));
For<IApplicationConfigurationSection>()
.Use(GetConfig());
Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());
}
private IApplicationConfigurationSection GetConfig()
{
var config = ConfigurationManager.GetSection("application") as ApplicationConfigurationSection;
return config; // this always returns a valid instance
}
}
`Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());`