使用structuremap 2.6.4.1,我的容器配置如下:
existingContainer.Configure(expression =>
{
expression.For<IDocumentSession>()
.HybridHttpOrThreadLocalScoped()
.Use(container =>
{
var store = container.GetInstance<IDocumentStore>();
return store.OpenSession();
});
}
Run Code Online (Sandbox Code Playgroud)
HybridHttpOrThreadLocalScoped 在结构图3中不存在,所以我的问题是,structuremap 3中的等效配置是什么?
我有一个使用Structuremap的ASP MVC 4应用程序.我正在尝试通过Structuremap拦截向我的应用程序添加日志记录.在注册表中,我扫描一个特定的程序集,以便使用默认约定注册它的所有类型:
public class ServicesRegistry : Registry
{
public ServicesRegistry()
{
Scan(x =>
{
x.AssemblyContainingType<MyMarkerService>();
x.WithDefaultConventions();
});
}
}
Run Code Online (Sandbox Code Playgroud)
拦截器:
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var watch = Stopwatch.StartNew();
invocation.Proceed();
watch.Stop();//log the time
}
}
Run Code Online (Sandbox Code Playgroud)
我可以为一个特定的插件类型添加拦截器,如下所示:
var proxyGenerator = new ProxyGenerator();
container.Configure(x => x.For<IServiceA>().Use<ServiceA>().DecorateWith(instance => proxyGenerator.CreateInterfaceProxyWithTarget(instance, new LogInterceptor())));
Run Code Online (Sandbox Code Playgroud)
但是我想让结构图为在注册表中扫描的所有类型创建日志代理.有没有办法实现这个目标?
我有一个非常奇怪的问题 StructureMap.MVC5
我在Visual Studio中创建了一个全新的MVC5项目(选择了ASP.net MVC项目的默认选项.)
然后我通过nuget包管理器(Install-Package StructureMap.MVC)安装了structuremap.mvc5 .
然后我将以下代码添加到"HomeController.cs"文件的顶部:
namespace TestMVC.Controllers
{
public interface ITest
{
string TestMessage();
}
public class Test : ITest
{
public string TestMessage()
{
return "this worked again 23";
}
}
Run Code Online (Sandbox Code Playgroud)
然后我添加了一个构造函数和私有成员,如下所示:
public class HomeController : Controller
{
private readonly ITest _test;
public HomeController(ITest test)
{
_test = test;
}
Run Code Online (Sandbox Code Playgroud)
最后,我更新了About操作结果,如下所示:
public ActionResult About()
{
ViewBag.Message = _test.TestMessage();
return View();
}
Run Code Online (Sandbox Code Playgroud)
该项目编译并启动.我得到了正常的默认索引页面,但是在浏览器中返回页面后的2到5秒之间,我在return此方法的行中的"StructureMapDependencyScope.cs"中抛出异常:
private HttpContextBase HttpContext {
get {
var ctx = …Run Code Online (Sandbox Code Playgroud) 我有一个Web API项目,它使用StructureMap作为其DI.它已经工作了一段时间,但我在Web API帮助页面(Microsoft.AspNet.WebApi.HelpPage)中遇到了一些问题,其中由于空堆栈而抛出InvalidOperationExceptions.
我使用帮助页面创建了一个新的Web API项目,它可以正常工作,直到我添加StructureMap.WebApi2包,而前面提到的异常在这里抛出,在ModelDescriptionLink.cshtml中
else if (modelDescription is CollectionModelDescription)
{
var collectionDescription = modelDescription as CollectionModelDescription;
var elementDescription = collectionDescription.ElementDescription;
@:Collection of @Html.DisplayFor(m => elementDescription.ModelType, "ModelDescriptionLink", new { modelDescription = elementDescription })
}
else
{
@Html.DisplayFor(m => modelDescription)
}
Run Code Online (Sandbox Code Playgroud)
@:Collection of @Html.DisplayFor(m => elementDescription.ModelType, "ModelDescriptionLink", new { modelDescription = elementDescription })当它试图显示该模型的资源描述的链接时,它会被抛出.
这是一条精简的路线仍然会导致异常:
[Route("Test")]
public IHttpActionResult Post([FromBody] IEnumerable<MySimpleModel> models)
{
return null;
}
Run Code Online (Sandbox Code Playgroud)
试图访问此路由的文档http://localhost:21966/Help/Api/POST-Test会导致异常:

我只能找到一个有相同问题的人的例子,他们的解决方案是从StructureMap切换到Ninject或避免使用null检查的异常.
这是堆栈跟踪的顶部:
[InvalidOperationException: Stack empty.]
System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +52
System.Collections.Generic.Stack`1.Peek() +6693321
System.Web.WebPages.WebPageBase.get_Output() …Run Code Online (Sandbox Code Playgroud) 我们正在使用StructureMap 3.1.6.186并且遇到覆盖特定插件的问题.在我们的例子中,我们有一个控制台应用程序,我们正在部署到远程服务器.控制台应用程序对实现的依赖性非常高,需要在服务器上安装一些不需要的COM对象.由于我们确实知道在控制台应用程序中实际上没有使用此特定依赖项,因此我们尝试使用我在控制台应用程序主Program.cs中创建的虚假实现来覆盖有问题的特定实现(IImageManipulator).这将减少在服务器上安装这些com对象的需要,并且不会破坏控制台应用程序.
正如你从代码和下面的评论,既不IImageManipulator的在容器构造底部的显式注册,也不容器建成后的映射注射看到显示为预期工作.有趣的是,当我在控制台应用程序中获得IImageManipulator的实例时,它为我提供了所需的FakeImageManipulator实现.但是,当我获得IEndItemService的实例时,底层实现是我不想要的另一种类型.
任何想法如何覆盖特定接口的所有实现,即使有其他注册表已注册此接口?万分感谢!
public class FakeImageManipulator : IImageManipulator
{
public Dictionary<ImageMetaDataEnum, string> GetMetaData(Image image, params ImageMetaDataEnum[] desiredMetaData)
{
throw new NotImplementedException();
}
}
public override void ProgramLogic()
{
IContainer container = new Container(registry =>
{
registry.ForSingletonOf<ITypeResolver>().Use<StructureMapTypeResolver>();
registry.ForSingletonOf<ILogger>().Use(() => MessageLogger.GetInstance());
registry.ForSingletonOf<IConfigParser>().Use(() => ConfigParser.GetInstance());
registry.Scan(scan =>
{
scan.AssemblyContainingType<ServiceRegistry>();
scan.LookForRegistries();
});
//--hoping this would override anything that was already set in another registry
registry.For<IImageManipulator>().Use(() => new FakeImageManipulator());
});
container.Model.For<IImageManipulator>().Default.EjectAndRemove();
//--hoping this would override anything that was already set in another registry
container.Inject(typeof(IImageManipulator), …Run Code Online (Sandbox Code Playgroud) 我有一个现有的应用程序使用2.x版本的Structuremap中的最后一个版本,它工作正常.StructureMap 3刚刚上线,我决定尝试更新它,看看它是怎么回事.
但无论我做什么,我似乎无法正确解决当前用户.我不确定它是否试图在应用程序的生命周期中过早地构建依赖项或者交易可能是什么.因为最近的发布,几乎没有任何信息,我发现它还没有任何用处.
注册依赖项的行.
For<HttpContextBase>().Use(() => new HttpContextWrapper(HttpContext.Current));
For<ICurrentUser>().HybridHttpOrThreadLocalScoped().Use(x => GetCurrentUser(x));
Run Code Online (Sandbox Code Playgroud)
我解决依赖关系的方法
private ICurrentUser GetCurrentUser(IContext context)
{
try
{
var httpContext = context.GetInstance<HttpContextBase>();
if (httpContext == null) return null;
if (httpContext.User == null) return null;
var user = httpContext.User;
if (!user.Identity.IsAuthenticated) return null;
var personId = user.GetIdentityId().GetValueOrDefault();
return new CurrentUser(personId, user.Identity.Name);
}
catch (Exception ex)
{
context.GetInstance<ILogger>().Error("Error trying to determine the current user.", ex);
throw new Exception("Error trying to determine the current user.", ex);
}
}
Run Code Online (Sandbox Code Playgroud)
我的ICurrentUser接口
public interface ICurrentUser …Run Code Online (Sandbox Code Playgroud) 在StructureMap 2中我有这样的事情:
For<ILogger>().HybridHttpOrThreadLocalScoped().Use<Logger>();
Run Code Online (Sandbox Code Playgroud)
使用Structure Map 3时,我应该使用以下内容吗?
For<ILogger>().LifecycleIs<HybridLifecycle>().Use<Logger>();
Run Code Online (Sandbox Code Playgroud)
然后我尝试将相同的更改应用于:
For<IDispatcher>().Transient().Use<Dispatcher>();
Run Code Online (Sandbox Code Playgroud)
我无法使用:
For<IDispatcher>().LifecycleIs<Transient>().Use<Dispatcher>();
Run Code Online (Sandbox Code Playgroud)
为什么?
谢谢你,米格尔
我正在尝试使用Web API 2设置结构图ver 3.0.5.0.
我已经遵循了这个实现:使用ASP.NET Web API 2.1配置依赖注入
但是,在针对ComplexesController进行攻击时出现此错误:
尝试创建"ComplexesController"类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.
谁能看到我的structuremap配置有什么问题?永远不会调用Create方法.
这是我的实施:
public class StructureMapControllerActivator : IHttpControllerActivator
{
private readonly IContainer _container;
public StructureMapControllerActivator(IContainer container)
{
if (container == null) throw new ArgumentNullException("container");
_container = container;
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
try
{
var scopedContainer = _container.GetNestedContainer();
scopedContainer.Inject(typeof(HttpRequestMessage), request);
request.RegisterForDispose(scopedContainer);
return (IHttpController)scopedContainer.GetInstance(controllerType);
}
catch (Exception e)
{
// TODO : Logging
throw e;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法在我的创业公司......
public void InitializeContainer()
{
// STRUCTURE MAP …Run Code Online (Sandbox Code Playgroud) 我已升级到SM 3.0,现在,除了其他重大变化之外,我发现EqualToAppSetting已经消失.
我曾经能做到
.Use<SomeType>().Ctor<SomeType>("connectionStr").EqualToAppSetting("myAppSetting");
Run Code Online (Sandbox Code Playgroud)
当然,myAppSetting从app.config或web.config中提取.
现在有人知道怎么做吗?或其他一些工作?
我将使用UserName来跟踪“创建”和“修改”字段。为此,我直接在DbContext中引用了System.Web程序集:
public void auditFields()
{
var auditDate = DateTime.Now;
foreach (var entry in this.ChangeTracker.Entries<BaseEntity>())
{
switch (entry.State)
{
case EntityState.Detached:
break;
case EntityState.Unchanged:
break;
case EntityState.Added:
entry.Entity.CreatedOn = auditDate;
entry.Entity.ModifiedOn = auditDate;
entry.Entity.CreatedBy = HttpContext.Current.User.Identity.Name ?? "anonymouse";
entry.Entity.ModifiedBy = HttpContext.Current.User.Identity.Name ?? "anonymouse";
break;
case EntityState.Deleted:
break;
case EntityState.Modified:
entry.Entity.ModifiedOn = auditDate;
entry.Entity.ModifiedBy = HttpContext.Current.User.Identity.Name ?? "anonymouse";
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
它可以正常工作,但是将DbContext与HttpContext紧密结合在一起,如果我们将DbContext暴露在非Web环境中,这不是一个好主意。所以我用这种方式:
public class ApplicationDbContext :
IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>,
IUnitOfWork
{
public ApplicationDbContext()
: …Run Code Online (Sandbox Code Playgroud) structuremap3 ×10
structuremap ×8
c# ×5
asp.net-mvc ×2
.net ×1
aop ×1
arguments ×1
asp.net ×1
constructor ×1
dbcontext ×1