我想在代码中创建一个名为instance的Structuremap,而不需要配置文件
我希望能够像这样创建实例:
var namedInjector = ObjectFactory.GetNamedInstance<IInjectable>("Other");
Run Code Online (Sandbox Code Playgroud)
我无法在代码中定义这样的类型.我找到了这个示例,但它使用了以前版本的旧语法,并将命名实例定义为:
.ForRequestedType<MementoType>()
.AddConcreteType<ConcreteType>(instanceName)
Run Code Online (Sandbox Code Playgroud)
在最新的结构图版本中,没有.AddConcreteType(instanceName)方法,该方法采用实例名称.
所以我非常喜欢使用NHibernate,但总是使用Spring.Net.
我最近遇到了Jeremy Miller的StructureMap,并且比Spring.Net更喜欢它.在他的StructureMap网站上,他承诺一个关于如何一起使用NHibernate和StructureMap的例子.不幸的是,他没有时间去做(或者我找不到).
那么有没有人有关于如何使用StructureMap处理NHibernate会话的例子?
我们正在构建一个ASP.NET项目,并将所有业务逻辑封装在服务类中.有些是在域对象中,但通常那些是相当贫血的(由于我们正在使用的ORM,这不会改变).为了更好地启用单元测试,我们为每个服务定义接口并使用DI.例如,这里有几个接口:
IEmployeeService
IDepartmentService
IOrderService
...
Run Code Online (Sandbox Code Playgroud)
这些服务中的所有方法基本上都是任务组,并且这些类不包含私有成员变量(除了对依赖服务的引用).在我们担心单元测试之前,我们只是将所有这些类声明为静态并让它们直接相互调用.现在,如果服务依赖于其他服务,我们将设置这样的类:
public EmployeeService : IEmployeeService
{
private readonly IOrderService _orderSvc;
private readonly IDepartmentService _deptSvc;
private readonly IEmployeeRepository _empRep;
public EmployeeService(IOrderService orderSvc
, IDepartmentService deptSvc
, IEmployeeRepository empRep)
{
_orderSvc = orderSvc;
_deptSvc = deptSvc;
_empRep = empRep;
}
//methods down here
}
Run Code Online (Sandbox Code Playgroud)
这通常不是一个问题,但我想知道为什么不建立一个我们传递的工厂类呢?
即
public ServiceFactory
{
virtual IEmployeeService GetEmployeeService();
virtual IDepartmentService GetDepartmentService();
virtual IOrderService GetOrderService();
}
Run Code Online (Sandbox Code Playgroud)
然后而不是调用:
_orderSvc.CalcOrderTotal(orderId)
Run Code Online (Sandbox Code Playgroud)
我们打电话
_svcFactory.GetOrderService.CalcOrderTotal(orderid)
Run Code Online (Sandbox Code Playgroud)
这种方法的缺点是什么?它仍然是可测试的,它仍然允许我们使用DI(并通过工厂内外的DI处理外部依赖关系,如数据库上下文和电子邮件发件人),它消除了大量的DI设置并更多地整合了依赖关系.
谢谢你的想法!
我已经StructureMap多次使用MVC2/3而没有任何顾虑,但我想在MVC4中处理IoC是不同的.当我用于StructureMap处理MVC4中的IoC时,我得到以下异常:
为什么?我没有在谷歌找到任何正确的结果,除了这个:IoC不工作在MVC4 这些是我的IoC类:
public static class IoC {
public static IContainer Initialize() {
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
//scan.Assembly("DLL.Core");
scan.Assembly("DLL.CMS");
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
x.For<IDbContext>().Use<ModelEntities>();
x.For(typeof(IRepository<>)).Use(typeof(Repository<>));
x.For<IHttpControllerActivator>();
x.For<IController>();
});
return ObjectFactory.Container;
}
Run Code Online (Sandbox Code Playgroud)
而SmDependencyResolver是:
public class SmDependencyResolver : IDependencyResolver
{
private readonly IContainer _container;
public SmDependencyResolver(IContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
if (serviceType == null) return null;
try
{
return serviceType.IsAbstract || serviceType.IsInterface
? _container.TryGetInstance(serviceType)
: _container.GetInstance(serviceType);
}
catch …Run Code Online (Sandbox Code Playgroud) structuremap asp.net-mvc inversion-of-control asp.net-mvc-3 asp.net-mvc-4
抽象
在过去的几个月里,我一直在编写一个轻量级,基于C#的游戏引擎,它具有API抽象和实体/组件/脚本系统.它的整体想法是通过提供类似于Unity引擎的架构来简化XNA,SlimDX等游戏开发过程.
设计挑战
正如大多数游戏开发者所知,在整个代码中需要访问许多不同的服务.许多开发人员使用全局静态实例,例如渲染管理器(或作曲家),场景,图形设备(DX),记录器,输入状态,视口,窗口等.全局静态实例/单例有一些替代方法.一种是通过构造函数或构造函数/属性依赖注入(DI)为每个类提供它需要访问的类的实例,另一种是使用全局服务定位器,如StructureMap的ObjectFactory,其中服务定位器通常配置为一个IoC容器.
依赖注入
出于多种原因,我选择采用DI方式.最明显的一个是可测试性,通过对接口进行编程并具有通过构造函数提供给它们的每个类的所有依赖关系,这些类很容易测试,因为测试容器可以实例化所需的服务或它们的模拟,并输入到每个要测试的课程.进行DI/IoC的另一个原因是,不管你信不信,提高代码的可读性.没有更多的初始化过程实例化所有不同的服务,并通过引用所需服务手动实例化类.配置内核(NInject)/注册表(StructureMap)可以方便地为引擎/游戏提供单点配置,其中选择和配置服务实现.
我的问题
基本上做DI/IoC会大大降低我的工作效率,在某些情况下会进一步使代码和架构复杂化.因此,我不确定这是一条我应该遵循的道路,还是只是放弃并以老式的方式做事.我不是在寻找一个单一的答案,说明我应该或不应该做什么,而是讨论从长远来看使用DI是否值得,而不是使用全局静态/单一方式,可能的优点和缺点我忽略了处理DI时,上面列出的问题的可能解决方案.
我有一个配置了CI帖子的构建,运行了一些测试.虽然测试成功运行,但构建显示警告:
:无法为StructuremapMvc生成存根:type已密封.:无法为IUnitOfWork生成填充程序:type是一个接口.:无法为Repository.IRepository`1生成填充程序:type是一个接口.
等等.
我正在使用通用存储库模式以及工作单元.我为我的MVC WebApi项目(利用StructureMap利用依赖注入)和包含我的存储库和UnitOfWork的数据项目添加了Fake Assemblies.我已经探究过这个错误并且似乎有点确信这可能是由于假装配的限制,但我需要绝对确定我没有做错任何事
我有一个项目,我使用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中定义的连接字符串.
我正在使用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 ×10
c# ×3
asp.net-mvc ×2
unit-testing ×2
.net ×1
architecture ×1
irepository ×1
nhibernate ×1
ninject ×1
webactivator ×1