【问题标题】:StructureMap 2.5 and internal implementorsStructureMap 2.5 和内部实现者
【发布时间】:2010-12-05 07:02:30
【问题描述】:

是否有可能让这些东西工作(某种方式强制 Objectfactory 创建像 Activator 这样的实例)

在下面的示例中,所有内容都放在一个组件中

public interface IUnitOfWorkFactory
{
    IUnitOfWork Create();
}

internal class NHUnitOfWorkFactory : IUnitOfWorkFactory
{
    public IUnitOfWork Create()
    {
        ////  do needed stuff
    }
}

引导:

ObjectFactory.Configure(x =>
{
    x.ForRequesedType<IUnitOfWorkFactory>.TheDefaultIsConcreteType<NHUnitOfWorkFactory>();
}); 

用法:

IUnitOfWorkFactory factory = ObjectFactory.GetInstance<IUnitOfWorkFactory>();

我的结果:

Porktal.Core.Tests.UnitOfWorkTests.Can_Start_Unit_of_Work:StructureMap.StructureMapException:StructureMap 异常代码:207 创建 PluginType Porktal.Core.Data.IUnitOfWorkFactory 的实例 'Porktal.Core.Data.NH.NHUnitOfWorkFactory, Porktal.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 时出现内部异常。检查内部异常以获取更多详细信息。 ---- System.MethodAccessException:Porktal.Core.Data.NH.NHUnitOfWorkFactory..ctor() 堆栈跟踪: 在 StructureMap.Pipeline.ConfiguredInstanceBase`1.StructureMap.Pipeline.IConfiguredInstance.Build(Type pluginType, BuildSession session, InstanceBuilder builder) 在 StructureMap.Pipeline.ConfiguredInstanceBase`1.build(类型 pluginType,BuildSession 会话) 在 StructureMap.Pipeline.Instance.createRawObject(类型 pluginType,BuildSession 会话) 在 StructureMap.Pipeline.Instance.Build(类型 pluginType,BuildSession 会话) 在 StructureMap.Pipeline.BuildPolicy.Build(BuildSession buildSession, Type pluginType, Instance instance) 在 StructureMap.InstanceFactory.Build(BuildSession 会话,实例实例) 在 StructureMap.BuildSession.CreateInstance(类型 pluginType,Instance 实例) 在 StructureMap.BuildSession.b__0(类型 t) 在 StructureMap.Util.Cache`2.get_Item(KEY key) 在 StructureMap.BuildSession.CreateInstance(类型 pluginType) 在 StructureMap.Container.GetInstance(类型 pluginType) 在 StructureMap.Container.GetInstance[T]() 在 StructureMap.ObjectFactory.GetInstance[PLUGINTYPE]() 在 D:\Porktal\Porktal.Core\Bootstraper.cs:line 20 中的 Porktal.Core.Bootstraper.Bootstrap() 在 D:\Porktal\Porktal.Core.Tests\UnitOfWorkTests.cs:line 11 中的 Porktal.Core.Tests.UnitOfWorkTests.Can_Start_Unit_of_Work() ----- 内部堆栈跟踪 ----- 在 PorktalCoreDataNHNHUnitOfWorkFactoryInstanceBuilder44203c8113d44053be045df4db28c3dc.BuildInstance(IConfiguredInstance , BuildSession ) 在 StructureMap.Pipeline.ConfiguredInstanceBase`1.StructureMap.Pipeline.IConfiguredInstance.Build(Type pluginType, BuildSession session, InstanceBuilder builder)

【问题讨论】:

    标签: c# .net structuremap access-modifiers


    【解决方案1】:

    您有 2 个选项。您可以将 NHUnitOfWorkFactory 设为公开(首选)。

    或者您可以将构建内部类的代码以 lambda 的形式放入程序集中(它可以访问内部成员),并将其传递给 StructureMap:

    ObjectFactory.Configure(x => {
      x.ForRequestedType<IUnitOfWorkFactory>()
       .TheDefault.Is.ConstructedBy(() => new NHUnitOfWorkFactory())
    });
    

    与较新版本的 StructureMap 等效的是:

    ObjectFactory.Configure(x => {
      x.For<IUnitOfWorkFactory>().Use(() => new NHUnitOfWorkFactory())
    });
    

    【讨论】:

    • 我为公众舆论加了一个 +1。
    • 在较新版本的 StructureMap 中,首选用法是:x.For().Use(new NHUnitOfWorkFactory());
    • 理查德 - 这是不正确的(但一个常见的错误)。您的示例将创建一个在注册时实例化的单例 NHUnitOfWorkFactory。我的示例展示了在请求时为每个请求创建一个新的工厂实例。我已经用正确的新语法更新了我的答案。
    • 事实证明这在实践中并不能很好地工作,如果你试图避免公开的事情依赖于其他内部构造函数注入的类。例如想象一下你的内部类A 实现了公共接口IA,但是A 的构造函数依赖于内部接口IB。您需要调用ObjectFactory.Configure 来映射IA=>AIB=>B。当然,如果B 的构造函数依赖于IC,那么ID 等等...你最终会公开所有内容:(
    • @JoshuaFlanagan 甚至 Use(() =&gt; new NHUnitOfWorkFactory()) 创建一个单身人士。 lambda 表达式只调用一次。
    【解决方案2】:

    我还没有验证这一点,但是使 NHUnitOfWorkFactory 程序集的内部对 StructureMap 程序集可见可能会奏效。

    您在 AssemblyInfo 类中使用 InternalsVisibleTo 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      相关资源
      最近更新 更多