我还在尝试使用StructureMap来解决问题,而我遇到的一个问题是我的Controller Factory类在传递空控制器类型时会爆炸.这仅在应用程序第一次构建时发生,之后每个后续构建都可以正常工作.即使我关闭Visual Studio并重新打开项目(我没有在IIS中运行它).这几乎就像有某种缓存一样.这是控制器类的样子:
public class IocControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
try
{
return (Controller)ObjectFactory.GetInstance(controllerType);
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
可能有什么不对?我是否需要注册每个控制器?谢谢.
我有一个项目,我使用StructureMap进行依赖注入.该项目作为MVC项目编译良好,但在将所有内容移动到MVC2项目后,我现在收到以下错误:
Test.Web.Controllers.StructureMapControllerFactory.GetControllerInstance(System.Type)':找不到合适的方法来覆盖C:\ Test\Web\Controllers\StructureMapControllerFactory.cs 11 40 Test.Web
这是我的StructureMapControllerFactory:
using System;
using System.Web.Mvc;
using StructureMap;
namespace Test.Web.Controllers
{
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)**
{
IController result = null;
try
{
if (controllerType == null) return base.GetControllerInstance(controllerType);
result = ObjectFactory.GetInstance(controllerType) as Controller;
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
return result;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我找到了一个与此问题半关联的帖子,但它没有提供任何关于如何解决我的问题的见解:MVC 2预览1 - 控制器中带参数的方法无法加载
显然我必须错过1.0-2.0级别的变化,但我不确定是什么改变了.任何帮助总是受到赞赏.
我个人喜欢从C#代码配置StructureMap的选项.根据我的理解,DI的优点之一是我们可以轻松交换新的具体实例.但是,如果配置是在代码中定义的,那么具体实例在dll中是硬编码的.
所以,实际上,它与硬件编码依赖关系一样好,对吧?我知道,在测试过程中它会让生活更轻松......
我的观点是,使用xml配置不是更好吗?你想插入一个新的具体实例?只需让安装程序用新的文件覆盖structuremap.config文件.
那么,配置StructureMap的首选方法是什么?
额外:我暂时被迫使用C#配置,因为我不知道如何将连接字符串传递给实例.我可以在配置文件中编写连接字符串,但我想重用app.config中定义的连接字符串.
我一直在玩ASP.NET MVC RC2中的DI支持.
我已经为NHibernate的每个请求实现了会话,并且需要注入ISession我的"工作单元"动作过滤器.
如果我直接引用StructureMap容器(ObjectFactory.GetInstance)或使用DependencyResolver来获取我的会话实例,一切正常:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试使用我的StructureMap过滤器提供程序(继承FilterAttributeFilterProvider),我在请求结束时提交NHibernate事务时遇到问题.
就像ISession在请求之间共享对象一样.我经常看到这一点,因为我的所有图像都是通过MVC控制器加载的,因此我在正常页面加载时创建了20个左右的NHibernate会话.
我在动作过滤器中添加了以下内容:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
public ISession SessionTest { get; set; }
public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext) {
bool sessionsMatch = (this.Session == this.SessionTest);
Run Code Online (Sandbox Code Playgroud)
使用StructureMap过滤器提供程序注入SessionTest.
我发现在一个有20个图像的页面上,"sessionsMatch"对于2-3个请求是假的.
我对会话管理的StructureMap配置如下:
For<ISessionFactory>().Singleton().Use(new NHibernateSessionFactory().GetSessionFactory());
For<ISession>().HttpContextScoped().Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
Run Code Online (Sandbox Code Playgroud)
在global.asax中,我在每个请求结束时调用以下内容:
public Global() {
EndRequest += (sender, e) => {
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
};
}
Run Code Online (Sandbox Code Playgroud)
这个配置线程安全吗?以前我使用自定义将依赖项注入到同一个过滤器中IActionInvoker.当我开始遇到上述问题时,这一直工作到MVC 3 RC2,这就是为什么我认为我会尝试使用过滤器提供程序.
任何帮助,将不胜感激. …
如果我在每个Repository类中使用此代码,那么我可以使SQL分析工作,但我想将每个类的代码移动到StructureMap处理DB的类中.
存储库类的示例:
public DB CreateNewContext()
{
var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["connection"].ConnectionString);
var profiledConnection = ProfiledDbConnection.Get(sqlConnection);
return DataContextUtils.CreateDataContext<DB>(profiledConnection);
}
public SqlRecipeRepository(DB dataContext)
{
_db = CreateNewContext();
}
Run Code Online (Sandbox Code Playgroud)
现在我想将dataContext变量作为配置文件版本,因此来自我的DBServiceRegistry类.
这是DBServiceRegistry类:
public class DBServiceRegistry : Registry
{
public DBServiceRegistry()
{
var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["GetMeCooking.Data.Properties.Settings.server"].ConnectionString);
var profiledConnection = ProfiledDbConnection.Get(sqlConnection);
For<DB>().HybridHttpOrThreadLocalScoped().Use(() => DataContextUtils.CreateDataContext<DB>(profiledConnection));
//Original method just had this:
//For<DB>().HybridHttpOrThreadLocalScoped().Use(() => new DB());
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码不会导致任何错误,但我没有得到SQL分析,我做错了什么?
structuremap是否允许您以懒惰的方式进行构造函数注入?意思是不创建在使用之前注入的对象?
我正在使用FluentValidation库对我的某个模型强制执行唯一约束:
public class Foo {
// No two Foos can have the same value for Bar
public int Bar { get; set; }
}
public class FooValidator : AbstractValidator<Foo> {
public FooValidator(ApplicationDbContext context) {
this.context = context;
RuleFor(m => m.Bar)
.Must(BeUnique).WithMessage("Bar must be unique!");
}
private readonly ApplicationDbContext context;
public bool BeUnique(int bar) {
return !context.Foos.Any(foo => foo.Bar == bar);
}
}
Run Code Online (Sandbox Code Playgroud)
该ApplicationDbContext值是使用StructureMap注入.为了确保在每个请求结束时处理上下文,我试图调用我的应用程序ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()的EndRequest处理程序.
不幸的是,似乎Application_EndRequest在我的验证器类能够完成其工作之前调用该方法,并且在FooValidator.BeUnique执行时间时处理上下文.
有没有更好的方法来使用FluentValidation库执行数据库相关的验证,或者是将此逻辑移动到其他位置的唯一解决方案(控制器操作,数据库本身,或者其他地方)?
structuremap entity-framework dependency-injection fluentvalidation asp.net-mvc-3
我正在将ASP.NET MVC3项目转换为MVC4.我试图找到使用StructureMap和MVC4的最佳方法.我找到了一些可行的解决方案,但尚未尝试过.
第一种解决方案非常简单轻便.第二个(Structuremap.MVC4)依赖于WebActivator进行启动.
什么是更好,最简单的方法?我是否仍需要引导所有内容并使用WebActivator设置DependencyResolver?
谢谢你的帮助.
在StructureMap,我们可以代理TInterface,并TConcreteImpl与TProxy这个这一点:
ConfigurationExpression config = ...
config.For<TInterface>().DecorateAllWith<TProxy>();
config.For<TInterface>().Use<TConcreteImpl>();
Run Code Online (Sandbox Code Playgroud)
我想使用DispatchProxy(并在方法调用之前和调用之后全局记录),并为从StructureMap实例化的所有类型全局注册它,我想知道如何实现这一点?
更具体地说,我要对要实例化的所有类型运行以下命令:
TConcreteImpl instance = ...
TInterface proxy = DispatchProxyGenerator.CreateProxyInstance(typeof (TInterface), typeof (TProxy))
.SetParameters(instance);
Run Code Online (Sandbox Code Playgroud)
我已经尝试过IInstancePolicyStructureMap,但是没有成功,因为Instance它不是实际的对象实例。
public class Policy : IInstancePolicy
{
public void Apply(Type pluginType, Instance instance)
{
}
}
Run Code Online (Sandbox Code Playgroud)
非常感谢
我在结构图中有最简单的循环依赖 - 类A在其构造函数中依赖于类B,而类B在其构造函数中依赖于类A. 为了打破依赖,我让B类把A类作为属性,而不是构造函数参数,但是structmap仍然抱怨.
我已经看到在其他DI框架中使用此方法破坏了循环依赖 - 这是Structuremap的问题还是我做错了什么?
编辑: 我应该提到类B的属性是一个A类实例的数组,这样连线:
x.For<IB>().Singleton().Use<B>().Setter(y => y.ArrayOfA).IsTheDefault();
Run Code Online (Sandbox Code Playgroud)
为了澄清,我希望发生以下事件序列:
我希望所有这一切都发生在使用自动装配,如果可能的话......
编辑2:这是一个使用显式连线的简化示例:
interface ILoader { }
interface ILoaderManager { }
class Loader : ILoader
{
public Loader(ILoaderManager lm) { }
}
class LoaderManager : ILoaderManager
{
public ILoader Loader { get; set; } // Was an array, but same circular dependency appears here
}
ObjectFactory.Configure
(
x =>
{
x.For<ILoader>.Singleton().Use<Loader>();
x.For<ILoaderManager>().Singleton().Use<LoaderManager>().OnCreation((c, a) => a.Loader = c.GetInstance<ILoader>());
}
);
Run Code Online (Sandbox Code Playgroud)
验证配置会导致"使用RequestedType检测到双向依赖性问题:IocTest2.ILoader ..."
structuremap ×10
c# ×3
.net ×1
.net-core ×1
asp.net-mvc ×1
controller ×1
dependencies ×1
linq-to-sql ×1
nhibernate ×1
null ×1
webactivator ×1