【问题标题】:UNITY: passing in a new datacontext each time?UNITY:每次都传入一个新的数据上下文?
【发布时间】:2010-12-14 08:34:30
【问题描述】:

我正在尝试使用 unity 每次使用新实例自动在我的存储库中注入数据上下文..,我的想法是确保每次注入新的数据上下文

目前创建存储库失败,我认为它无法解析 MyDataContext

在“存储库”(见下文)上创建构造函数以获取存储库中的 DataContext 之前,一切正常,但现在失败了..

我目前在我在 global.asax 中创建的统一容器中有这个设置,我还注册了 MyDataContext 类型,它是标准 DataContext

        container = new UnityContainer();

        Container.RegisterType<MyDataContext, MyDataContext>()
            .RegisterType<IOfficeRepository, OfficeRepository>()
            .RegisterType<IOfficeService, OfficeService>();

基本上我有一个像这样调用存储库的服务

public class OfficeService : IOfficeService
{

    IOfficeRepository repository = null;

    public OfficeService(IOfficeRepository repository)
    {
        this.repository = repository;

        if (this.repository == null)
            throw new InvalidOperationException("Repository cannot be null");
    }

这是我的仓库

public class OfficeRepository : IOfficeRepository
{
    private MyDataContext db;

    public OfficeRepository (MyDataContext dataContext)
    {
        this.db = dataContext;
    }

编辑

我差点忘了我这样做是为了创建服务

officeService = Bootstrapper.Container.Resolve<IOfficeService>();

编辑 - 正在生成的错误

 Resolution of the dependency failed, type = "MarkSmith.IOfficeService", name = "".
 Exception message is: The current build operation (build key Build 
 Key[MarkSmith.OfficeService, null]) failed: The parameter repository could not be 
 resolved when attempting to call constructor 
 MarkSmith.OfficeService(MarkSmith.IOfficeRepository repository). (Strategy type BuildPlanStrategy, index 3)

编辑 - 删除存储库上的构造函数

这与数据上下文有关,因为如果我删除了存储库上采用 DataContext 的构造函数,那么一切正常,但我当然需要它接受一个 DataContext 才能每次都注入一个“新”数据上下文

public class OfficeRepository : IOfficeRepository
{
    private MyDataContext db new MyDataContext(); // CHANGE

    //public OfficeRepository (MyDataContext dataContext)
    //{
        //this.db = dataContext;
    //}

编辑 - 实际错误

深入挖掘后,我发现了这个错误......

The type MyDataContext has multiple constructors of length 2. 
Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0)
(Strategy type BuildPlanStrategy, index 3)

编辑 - 用 1 行代码测试以解决数据上下文

这也会失败并出现与上述相同的错误 - 多个构造函数

  MyDataContext test = Bootstrapper.Container.Resolve<MyDataContext >();

编辑 - 我的数据上下文中的所有构造函数

这些是由外部工具创建的,但一切都应该很好..

    [System.Diagnostics.DebuggerNonUserCode]
    public MyDataContext()
        : base(ConnectionString, mappingCache)
    {
        OnCreated();
    }

    [System.Diagnostics.DebuggerNonUserCode]
    public MyDataContext(string connection)
        : base(connection, mappingCache)
    {
        OnCreated();
    }

    [System.Diagnostics.DebuggerNonUserCode]
    public MyDataContext(System.Data.IDbConnection connection)
        : base(connection, mappingCache)
    {
        OnCreated();
    }

    [System.Diagnostics.DebuggerNonUserCode]
    public MyDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource)
        : base(connection, mappingSource)
    {
        OnCreated();
    }

    [System.Diagnostics.DebuggerNonUserCode]
    public MyDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource)
        : base(connection, mappingSource)
    {
        OnCreated();
    }

编辑 - 演示在没有 Unity 的代码中创建 DataContext 100% 没有问题

   MyDataContext tes2t = new MyDataContext ();

【问题讨论】:

  • 更新问题以显示我如何使用统一解决我的服务
  • 如果您尝试在不同点使用解析 MyDataContext 实例会发生什么?一切似乎都井井有条,但这可能会给我们一个线索。
  • 另外,第一个代码提取中是否有缺失行或拼写错误?看起来containerContainer 将是不同的实例。您可以使用调试器检查您是否拥有预期的实例。
  • 我用错误消息更新了问题“该类型有多个长度为 2 的构造函数。无法消除歧义。”
  • 好的,那么...MyDataContext 是否还有其他我们不知道的构造函数?

标签: linq-to-sql dependency-injection unity-container ioc-container datacontext


【解决方案1】:

有多个构造函数可供选择,Unity 不知道该使用哪一个。它将选择具有最多可满足所有参数的参数,但在这种情况下,有两个构造函数,每个构造函数都有两个可解析的参数。

如果您不想将 MyDataContext 类耦合到 Unity 并使用 Scott 建议的 InjectionConstructor 属性(赞成 :)),您可以指定在注册时使用的构造函数流畅的界面。详情请见Configuring Constructor, Property, and Method Injection

【讨论】:

    【解决方案2】:

    我不确定这是否有效,但您是否尝试将 MyDataContext 注册为组件而不是类型映射?

    container.RegisterType<MyDataContext>();
    

    而不是

    container.RegisterType<MyDataContext, MyDataContext>();
    

    根据新信息进行编辑

    罪魁祸首似乎是 MyDataContext 有多个构造函数。这是大多数 DI 容器的常见问题,因为它们只需要选择和使用一个。如果您可以通过将 MyDataContext 限制为只有一个构造函数来消除歧义,那可能是最简单的解决方案。

    否则,您应该能够在注册存储库时使用 InjectionConstructor 实例来识别构造函数。假设您要使用将连接字符串作为参数的构造函数:

    string connectionString =
        ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
    var injectedConnectionString = new InjectionConstructor(connectionString);
    container.RegisterType<MyDataContext>(injectedConnectionString);
    

    【讨论】:

    • 谢谢马克,我确实试过了,结果是一样的。我已经用具体错误更新了我的问题..
    • 更新的问题也显示删除构造函数的工作,但我当然需要构造函数来接受 DataContext - 有什么想法吗?
    • 谢谢马克!太好了,谢谢你..现在试试.. 1秒!谢谢
    • 太棒了!你整理好了!!我每天都学到新东西!我采取了快捷方式,因为我对 0 参数感兴趣,所以我这样做了......它似乎工作 RegisterType(new InjectionConstructor());
    • 关于删除构造函数,这不是一个真正的选择,因为它是由外部工具创建的,谁知道有一天我可能需要它们.. :-) ... 但是传入 InjectionConstructor 效果很好
    【解决方案3】:

    我没有看到您的 MyDataContext 构造函数;但尝试将 [InjectionConstructor] 属性添加到您要使用的属性中。

    【讨论】:

    • 这应该可行,但会将 MyDataContext 紧密耦合到 Unity。
    • 这个事实确实有效!!!但正如 Mark 所指出的,它的紧密耦合以及我的数据上下文是由外部工具创建的,因此该属性将被覆盖......我真的不完全理解为什么统一有问题,我对任何构造函数都不感兴趣(即具有 2 个 apram 的构造函数)我只对零参数构造函数感兴趣,当然只有 1 个……有替代方案吗???
    猜你喜欢
    • 2012-03-06
    • 2016-07-21
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多