UNITY:每次传递一个新的datacontext?

时间:2009-11-08 12:56:26

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

我正在尝试使用unity来每次使用新实例在我的存储库中自动注入datacontext ..我的想法是确保每次注入新的datacontext

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

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

我目前在我的Unity容器中有这个设置,我在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然后一切正常,但当然我需要它接受一个DataContext,每次都能注入一个“NEW”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行代码解析DATACONTEXT

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

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

编辑 - 我的DATACONTEXT上的所有结构

这些是由exernal util创建的,但一切都应该很好..

    [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 ();

3 个答案:

答案 0 :(得分:10)

我不确定这是否有效,但您是否尝试将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);

答案 1 :(得分:3)

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

如果您不想将MyDataContext类与Unity结合并使用Scott(upvoted :)建议的InjectionConstructor属性,则可以指定应该在使用流畅的界面进行注册的时间。有关详细信息,请参阅Configuring Constructor, Property, and Method Injection

答案 2 :(得分:1)

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