我想为structuremap中的类型注册一个对象的特定实例,我该怎么做?
例如,
当我做:
var myObj = ObjectFactory.GetInstance(typeof(MyAbstractClass));
Run Code Online (Sandbox Code Playgroud)
我希望它返回一个以前构造的具体类,我创建如下:
var myClass = new MyConcreteClass("bla"); // MyConcreteClass : MyAbstractClass
Run Code Online (Sandbox Code Playgroud)
所以
myObj == myClass
Run Code Online (Sandbox Code Playgroud)
如何使用structuremap注册myClass以方便此操作?
谢谢
安德鲁
是否可以使这些东西工作(某种方式强制Objectfactory创建像Activator这样的实例)
在下面的例子中,所有东西都放在一个sigle组件中
public interface IUnitOfWorkFactory
{
IUnitOfWork Create();
}
internal class NHUnitOfWorkFactory : IUnitOfWorkFactory
{
public IUnitOfWork Create()
{
//// do needed stuff
}
}
Run Code Online (Sandbox Code Playgroud)
引导:
ObjectFactory.Configure(x =>
{
x.ForRequesedType<IUnitOfWorkFactory>.TheDefaultIsConcreteType<NHUnitOfWorkFactory>();
});
Run Code Online (Sandbox Code Playgroud)
用法:
IUnitOfWorkFactory factory = ObjectFactory.GetInstance<IUnitOfWorkFactory>();
Run Code Online (Sandbox Code Playgroud)
我的结果:
Porktal.Core.Tests.UnitOfWorkTests.Can_Start_Unit_of_Work : StructureMap.StructureMapException : StructureMap Exception Code: 207 Internal exception while creating Instance 'Porktal.Core.Data.NH.NHUnitOfWorkFactory, Porktal.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' of PluginType Porktal.Core.Data.IUnitOfWorkFactory. Check the inner exception for more details. ---- System.MethodAccessException : Porktal.Core.Data.NH.NHUnitOfWorkFactory..ctor() Stack Trace: at StructureMap.Pipeline.ConfiguredInstanceBase`1.StructureMap.Pipeline.IConfiguredInstance.Build(Type pluginType, BuildSession session, InstanceBuilder builder) at StructureMap.Pipeline.ConfiguredInstanceBase`1.build(Type …
我正在使用structuremap在控制器中注册服务,我也需要在服务中注册存储库.我将如何做到这一点,因为他们是2个不同的项目,需要完全相同的IOC注册.实际上我在表示层使用它并在控制器中注入服务.我需要知道一个很好的实践方法,使用相同的IOC容器,在两个项目中注入.
使用structuremap引导dll的最佳方法是什么?我真的不希望图书馆的消费者在他们不想要的时候自己配置任何东西.我认为.config可能是最简单的,但是2.6.1已经出来了,我还不熟悉它的许多功能/变化.
为什么我更喜欢Unity上的StructureMap?
我已经使用StructureMap超过一年了.而且这段时间我曾经有一个名为IoC的包装类,看起来像这样
class IoC {
public static T GetInstance<T>()
{
return (T)GetInstance(typeof(T));
}
public static IEnumerable<T> GetAllInstances<T>()
{
return ObjectFactory.GetAllInstances<T>();
}
public static IEnumerable GetAllInstances(Type type)
{
return ObjectFactory.GetAllInstances(type);
}
public static object GetInstance(Type type)
{
return ObjectFactory.GetInstance(type);
}
public static void Inject<T>(T obj)
{
ObjectFactory.Inject(obj);
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了包装器,假设我可能想在某个时候更改IoC容器.此时我觉得这很糟糕.一个原因是:我不能在我的代码中使用ObjectFactory做其他有趣的事情,我必须使用这个包装器.另一件事是:我们的代码不应该真正独立于DependencyInjection容器.
使用这种方法的优点/缺点是什么?
structuremap abstraction dependency-injection ioc-container wrapper
正如标题所说,当我还配置了命名实例时,structuremap不会返回默认实例.
这是我的类型注册:
/// <summary>
/// Initializes a new instance of the <see cref="CommandProcessingTypeRegistry"/> class.
/// </summary>
public CommandProcessingTypeRegistry()
{
For<ICommandProcessor>().Singleton().Use<CommandCoordinator>();
For<ICommandProcessor>().Singleton().Use<SystemCommandSwitch>().Named(typeof(SystemCommandSwitch).FullName);
For<ICommandProcessor>().Singleton().Use<TelephonyCommandSwitch>().Named(typeof(TelephonyCommandSwitch).FullName);
For<ICommandProcessor>().Singleton().Use<AudioCommandSwitch>().Named(typeof(AudioCommandSwitch).FullName);
For<ICommandProcessor>().Singleton().Use<TetraCommandSwitch>().Named(typeof(TetraCommandSwitch).FullName);
For<ICommandProcessor>().Singleton().Use<RadioCommandSwitch>().Named(typeof(RadioCommandSwitch).FullName);
For<ICommandProcessor>().Singleton().Use<SnapshotCommandSwitch>().Named(typeof(SnapshotCommandSwitch).FullName);
For<ICommandProcessor>().Singleton().Use<TakeNextCommandSwitch>().Named(typeof(TakeNextCommandSwitch).FullName);
}
Run Code Online (Sandbox Code Playgroud)
这就是我请求实例的方式:
_commandProcessor = _container.GetInstance<ICommandProcessor>(); // _container is the structuremap IContainer instance
Run Code Online (Sandbox Code Playgroud)
我希望上面的行返回CommandCoordinator实例,但返回TakeNextCommandSwitch实例.我在这做错了什么?
这两个是等价的吗?
1)var store = new DocumentStore();
For<IDocumentStore>().Use(store);
Run Code Online (Sandbox Code Playgroud)
2)var store = new DocumentStore();
For<IDocumentStore>().Singleton().Use(store);
Run Code Online (Sandbox Code Playgroud)
要么
For< IDocumentStore>().AlwaysUnique().Use(store);
Run Code Online (Sandbox Code Playgroud)
这两个都会返回没有重复实例的文档库的单例实例吗?
我有一个通用的界面:
public interface IRepository<T> { ... }
Run Code Online (Sandbox Code Playgroud)
我有这样的实现:
public class Repository<T> {
public Repository<T>() { ... }
}
Run Code Online (Sandbox Code Playgroud)
StructureMap(v 2.6.3)配置如下:
For(typeof(IRepository<>)).Use(typeof(Repository<>));
Run Code Online (Sandbox Code Playgroud)
当我尝试拉出IRepository<Something>StructureMap时,我得到了一个Repository<Something>预期的结果.万岁!
现在我添加了第二个构造函数,实现如下:
public class Repository<T> {
public Repository<T>() { ... }
public Repository<T>(string database) { ... }
}
Run Code Online (Sandbox Code Playgroud)
当我尝试获得一个IRepository<Something>现在,我得到一个例外,因为它默认尝试使用带有参数的新构造函数.嘘!
如何更改我的StructureMap配置,以便它知道使用无参数构造函数?
为了在ASP.NET WebApi中刷新对RavenDB的更改,我创建了以下Action Filter:
public class RavenDbUnitOfWorkAttribute : ActionFilterAttribute
{
public Func<IDocumentSession> SessionFactory { get; set; }
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var session = SessionFactory.Invoke();
if (session != null && actionExecutedContext.Exception == null)
{
session.SaveChanges();
}
base.OnActionExecuted(actionExecutedContext);
}
}
Run Code Online (Sandbox Code Playgroud)
为了注入,IDocumentSession我创建了一个IFilterProvider循环遍历每个过滤器的自定义,并使用setter注入(StructureMap)设置任何依赖项.
我想知道IFilterProvider作用域的实例.阅读这篇文章,看起来每个请求都会创建控制器.
目前,我正在IDocumentSession使用StructureMap 明确确定每个请求的范围.问题是,如果我依赖IDependencyScope(使用嵌套容器)将相同的实例IDocumentSession注入我的Action Filter?
进一步测试似乎Action Filters不使用与Controller相同的依赖范围.我宁愿不在控制器中使用代码来刷新会话.
structuremap ×10
c# ×4
.net ×1
abstraction ×1
asp.net-mvc ×1
generics ×1
ravendb ×1
wrapper ×1