我知道在StructureMap中,当我想将特定参数传递给对象的构造函数时,我可以从我的*.config文件(或它们引用的文件)中读取.
ForRequestedType<IConfiguration>()
.TheDefault.Is.OfConcreteType<SqlServerConfiguration>()
.WithCtorArg("db_server_address")
.EqualToAppSetting("data.db_server_address")
Run Code Online (Sandbox Code Playgroud)
但我想要做的是从调试模式下的一个配置设置和另一个在发布模式下读取.
当然,我可以环绕.EqualToAppSetting("data.db_server_address"),有#if DEBUG,但由于某些原因这些语句让我畏缩了一点,当我把他们.我想知道是否有某种方式与StructureMap库本身做到这一点.
那么我可以根据项目是在调试模式还是发布模式下为我的对象提供不同的设置?
我有一个基本控制器,定义如下,但是ISiteService从不执行的构造函数:
public class BaseController : Controller
{
private ISiteService _siteService;
public BaseController() {}
public BaseController(ISiteService siteService)
{
_siteService = siteService; // this never gets hit..
}
protected override void Initialize(RequestContext rc)
{
string host = ((rc.HttpContext).Request).Url.Host;
Site site = _siteService.GetSiteByHost(host); // so _siteService is null...
base.Initialize(rc);
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我为什么会这样吗?要使这个构造函数执行,我需要做什么?
实现BaseController的所有控制器都具有构造函数,这些构造函数接受StructureMap提供的各种参数,并执行所有这些构造函数.
我不知道它是否相关,但这就是我为依赖注入配置StructureMap的方法.
private void ConfigureNonOptionalDependencies()
{
// all other dependencies are registered same as this,
// and the constructors all get hit
ForRequestedType<ISiteService>()
.TheDefaultIsConcreteType<SiteService>();
}
Run Code Online (Sandbox Code Playgroud)
我对StructureMap不熟悉,所以我不知道它是否与这个问题有关,或者它是否更像是一个MVC问题.或者它甚至可能吗?谢谢
编辑:
另外,我试过这个:
public …Run Code Online (Sandbox Code Playgroud) 我正在努力理解StructureMap的部分用法.特别是,在文档中有一个关于常见反模式的声明,仅使用StructureMap作为服务定位器而不是构造函数注入(直接来自Structuremap文档的代码示例):
public ShippingScreenPresenter()
{
_service = ObjectFactory.GetInstance<IShippingService>();
_repository = ObjectFactory.GetInstance<IRepository>();
}
Run Code Online (Sandbox Code Playgroud)
代替:
public ShippingScreenPresenter(IShippingService service, IRepository repository)
{
_service = service;
_repository = repository;
}
Run Code Online (Sandbox Code Playgroud)
这对于一个非常短的对象图很好,但是当处理很多级别的对象时,这是否意味着你应该从顶部向下传递更深层对象所需的所有依赖项?当然,这会破坏封装并暴露有关更深层对象实现的过多信息.
假设我正在使用Active Record模式,因此我的记录需要访问数据存储库才能保存和加载自身.如果此记录加载到对象内,该对象是否调用ObjectFactory.CreateInstance()并将其传递给活动记录的构造函数?如果该对象在另一个对象内部怎么办?是否将IRepository作为自己的参数进一步向上?这将向父对象公开我们此时访问数据存储库的事实,外部对象可能不应该知道.
public class OuterClass
{
public OuterClass(IRepository repository)
{
// Why should I know that ThingThatNeedsRecord needs a repository?
// that smells like exposed implementation to me, especially since
// ThingThatNeedsRecord doesn't use the repo itself, but passes it
// to the record.
// Also where do I create repository? Have to instantiate …Run Code Online (Sandbox Code Playgroud) structuremap dependency-injection service-locator constructor-injection
我使用StructureMap,EF 4.1/POCO.控制台应用程序假设在某些数据集上运行2个后续操作,比如说operation1和operation2.我将DbContext设置为单例.这会导致操作2出现问题,因为operation1在其DbContext中留下了一些垃圾,这会阻止operation2正常工作.同时我无法将DbContext设置为"每次调用".coz operation1使用2个存储库共享通过其构造函数的相同DbContext.理想情况下,我需要在operation2之前重新初始化/重置/清理DbContext.有任何想法吗?
谢谢
我需要StructureMap.ObjectFactory在ASP.NET MVC 3应用程序中初始化.
ObjectFactory.Initialize(x => x.For<Db>().HttpContextScoped().Use<Db>());
Run Code Online (Sandbox Code Playgroud)
我必须做的Application_BeginRequest还是Application_Start?
.net c# structuremap dependency-injection inversion-of-control
我刚刚开始尝试使用Web Api 2和StructureMap,已经安装了StructureMap.MVC4 Nuget包.在我尝试注册用户之前,一切似乎都运行良好.当IHttpControllerActivator的这个实现试图实例化一个控制器时,我得到了这个错误:
public class ServiceActivator : IHttpControllerActivator
{
public ServiceActivator(HttpConfiguration configuration) { }
public IHttpController Create(HttpRequestMessage request
, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
var controller = ObjectFactory.GetInstance(controllerType) as IHttpController;
return controller;
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily Microsoft.AspNet.Identity.IUserStore`1[[Microsoft.AspNet.Identity.EntityFramework.IdentityUser, Microsoft.AspNet.Identity.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], Microsoft.AspNet.Identity.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Run Code Online (Sandbox Code Playgroud)
我理解错误是什么,但不完全确定如何解决它.假设StructureMap中的默认扫描程序找不到IUserStore的默认实现是否正确?这是我使用的初始化代码:
ObjectFactory.Initialize(x => x.Scan(scan =>
{
scan.AssembliesFromApplicationBaseDirectory();
scan.WithDefaultConventions();
}));
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?谢谢.
编辑:我想我可能用这个解决了最初的问题:
x.For<Microsoft.AspNet.Identity.IUserStore<IdentityUser>>()
.Use<UserStore<IdentityUser>>();
Run Code Online (Sandbox Code Playgroud)
但现在还有另一个默认实例StructureMap无法解决 - dbcontext.这是我收到的下一条错误消息:
ExceptionMessage=StructureMap Exception Code: 202
No Default Instance defined for …Run Code Online (Sandbox Code Playgroud) structuremap dependency-injection basic-authentication asp.net-web-api
继我之前关于如何在结构图中实现IContainer的帖子之后,我已经打了一段时间我希望是我的最后一个问题了.
如何将其他(非结构图注入)对象传递给构造函数?
让我们从我用来测试这些东西的示例控制台应用程序中获取以下内容.
static void Main(string[] args)
{
_container = StructureMapConfig.GetContainer();
_userService = _container.GetInstance<IUserService>();
}
Run Code Online (Sandbox Code Playgroud)
抛出以下错误,因为我的构造函数有randomParam,而structuremap不知道如何填补空白:
StructureMap.dll中发生了一个未处理的"StructureMap.StructureMapBuildPlanException"类型异常
附加信息:无法为具体类型CommonServices.UserService创建构建计划
构造函数:
public UserService(IUserRepository userRepository, IStringService stringService, string randomParam)
{
_userRepository = userRepository;
_stringService = stringService;
}
Run Code Online (Sandbox Code Playgroud)
在我的注册表中,我定义了我的用户服务:
this.For<IUserService>().Use<UserService>();
Run Code Online (Sandbox Code Playgroud)
我的问题是如何以最简单的方式做到这一点?
我找到了这个链接,但看不到如何使用这些建议,因为我必须让我的调用类知道UserService的依赖关系.您可以看到其中一些是数据层项目,我不想告诉我的UI层有关它们.
http://structuremap.github.io/resolving/passing-arguments-at-runtime/
我在我的应用程序中使用了StructureMap和ASP.Net Identity.我有这条线的时候Application_Start
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
Run Code Online (Sandbox Code Playgroud)
这是StructureMapControllerFactory:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null && requestContext.HttpContext.Request.Url != null)
throw new InvalidOperationException(string.Format("Page not found: {0}",
requestContext.HttpContext.Request.Url.AbsoluteUri.ToString(CultureInfo.InvariantCulture)));
return ObjectFactory.GetInstance(controllerType) as Controller;
}
}
Run Code Online (Sandbox Code Playgroud)
return ObjectFactory.GetInstance(controllerType) as Controller;抛出StructureMapConfigurationException异常说:
No default Instance is registered and cannot be automatically determined for type 'IUserStore<Person>'
Run Code Online (Sandbox Code Playgroud)
但如果我删除ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());行一切正常,所以它的StructureMap的问题不是我的代码.
如果安装了StructureMap.MVC5 nuget包,并更新了structuremap nuget包,则ControllerConvention类将要求您实现ScanTypes方法(来自更新的IRegistrationConvention接口).这是方法签名:
public void ScanTypes(TypeSet types, Registry registry)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,
谢谢.
我收到此错误:
An exception of type 'System.NullReferenceException' occurred in PubStuff.Intern.Web.Internal.dll but was not handled in user code
Additional information: Object reference not set to an instance of an object
public class InternController : BaseController
{
IInternService _internService;
public InternController() { }
public InternController(IInternService internService)
{
_internService = internService;
}
// GET: Intern
public ActionResult Index()
{
object responseObject = null;
responseObject = _internService.GetAllSkills();
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
responseObject = _internService.GetAllSkills();函数,那么这一行就会抛出错误._internService为null
我该如何解决? 有什么问题?
更新 我最终遇到了StructureMap的问题,无论我是否添加了IInternUnitOfWork …
structuremap ×10
c# ×5
asp.net-mvc ×3
.net ×2
asp.net ×1
constructor ×1
controller ×1
dbcontext ×1
interface ×1
nuget ×1
poco ×1
web-config ×1