如何使用 Unity 在每次处理旧实例时解析新实例

发布于 2024-10-02 06:53:38 字数 1664 浏览 7 评论 0原文

我正在尝试开始使用 Unity,但我有一点库存。

我有一个 Context 类和一个由容器解析的 Repository 类。 我的 Repository 类采用 Context ctor 参数作为依赖项。

我的配置文件:

容器:

  <register type="IGeneralContext" mapTo="Data.EF.EFContext, Data.EF">
    <lifetime type="singleton" />
    <constructor>
      <param name="connectionString">
        <value value="anyConnStr"/>
      </param>
    </constructor>
  </register>

  <register type="IClienteRepository" mapTo="Repository.EF.ClientRepository, Repository.EF">
    <constructor>
      <param name="context">
        <dependency type="Data.EF.EFContext, Data.EF"/>
      </param>
    </constructor>
  </register>

现在,我希望在调用 Resolve 并且旧实例已经释放时构造 IGeneralContext 的新实例。

请参阅:

using (IGeneralContext context = container.Resolve<IGeneralContext>()) //NEW CONTEXT INSTANCE
{
    IClienteRepository rep = container.Resolve<IClienteRepository>(); // USE DEPENDENCY AS SINGLETON
    Cliente nc = new Cliente() {  };
    rep.Add(nc);
    context.CommitChanges();
} // DISPOSE CONTEXT

using (IGeneralContext context = container.Resolve<IGeneralContext>()) //BRAND NEW CONTEXT INSTANCE
{
    IClienteRepository rep = container.Resolve<IClienteRepository>(); // USE DEPENDENCY AS SINGLETON
    Cliente nc = new Cliente() { };
    rep.Add(nc);
    context.CommitChanges();
} // DISPOSE CONTEXT

IClienteRepository rep1 = container.Resolve<IClienteRepository>(); // NEW CONTEXT AGAIN
Cliente cliente1= rep1.GetById(1);

知道如何使用 Unity 解决这个问题吗?

谢了。

Im trying to start to use Unity but i got stock in a point.

I have a Context class and a Repository class being resolved by the container.
My Repository class take a Context ctor parameter as a Dependency.

My Config file:

container:

  <register type="IGeneralContext" mapTo="Data.EF.EFContext, Data.EF">
    <lifetime type="singleton" />
    <constructor>
      <param name="connectionString">
        <value value="anyConnStr"/>
      </param>
    </constructor>
  </register>

  <register type="IClienteRepository" mapTo="Repository.EF.ClientRepository, Repository.EF">
    <constructor>
      <param name="context">
        <dependency type="Data.EF.EFContext, Data.EF"/>
      </param>
    </constructor>
  </register>

And now, I want that a new instance of IGeneralContext get constructed when Resolve is called AND the old one was already released.

See:

using (IGeneralContext context = container.Resolve<IGeneralContext>()) //NEW CONTEXT INSTANCE
{
    IClienteRepository rep = container.Resolve<IClienteRepository>(); // USE DEPENDENCY AS SINGLETON
    Cliente nc = new Cliente() {  };
    rep.Add(nc);
    context.CommitChanges();
} // DISPOSE CONTEXT

using (IGeneralContext context = container.Resolve<IGeneralContext>()) //BRAND NEW CONTEXT INSTANCE
{
    IClienteRepository rep = container.Resolve<IClienteRepository>(); // USE DEPENDENCY AS SINGLETON
    Cliente nc = new Cliente() { };
    rep.Add(nc);
    context.CommitChanges();
} // DISPOSE CONTEXT

IClienteRepository rep1 = container.Resolve<IClienteRepository>(); // NEW CONTEXT AGAIN
Cliente cliente1= rep1.GetById(1);

Any idea how to solve it using Unity?

Tks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静待花开 2024-10-09 06:53:38

在分析了更好的詹姆斯建议后,我找到了一个不错的选择。

有一种新方法可以将实例化委托给工厂:

        container.RegisterType<IMyInterface, MyConcrete>(new InjectionFactory(c => MyFactoryClass.GetInstance()));

并且还可以扩展配置文件来为您完成此操作。

请参阅 CodePlex 上的 ctavares 帖子,他/她有一个非常好的示例。
http://unity.codeplex.com/Thread/View.aspx?ThreadId=219565

After analysing better James suggestion, I found a good alternative.

There is a new way to delegate the instantiations to a factory:

        container.RegisterType<IMyInterface, MyConcrete>(new InjectionFactory(c => MyFactoryClass.GetInstance()));

And also it is possible to extend the configuration file to do it for you.

See ctavares post at CodePlex, he/she has a very nice example.
http://unity.codeplex.com/Thread/View.aspx?ThreadId=219565

戴着白色围巾的女孩 2024-10-09 06:53:38

看一下 StaticFactory 扩展。您可以提供自己的对象创建方法,该方法允许您检测现有上下文是否仍然可用。

http://www.pnpguidance.net/post/RegisteringFactoryMethodCreateObjectsUnityStaticFactoryExtension.aspx

Take a look at the StaticFactory extension. You to supply your own method for object creation, which allows you to detect whether your existing context is still available.

http://www.pnpguidance.net/post/RegisteringFactoryMethodCreateObjectsUnityStaticFactoryExtension.aspx

掀纱窥君容 2024-10-09 06:53:38

您可能想退一步看看您的设计。我发现大多数时候我认为我需要一些复杂的 DI 配置,但问题实际上出在我的设计中。以下是您可以考虑的几个选项:

1) 使用工厂来创建存储库并向该工厂提供上下文:

var repositoryFactory = container.Resolve<IRepositoryFactory>();

using (var context = container.Resolve<IGeneralContext>())
{
    var rep = repositoryFactory.Create<IClienteRepository>(context);
    // ...
}

public class RepositoryFactory : IRepositoryFactory
{
    public TRepository Create<TRepository>(IGeneralContext context)
        where TRepository : IRepository
    {
        var repository = Container.Resolve<TRepository>();
        repository.Context = context;
        return repository;
    }
}

2) 尝试使存储库成为上下文的一部分:

using (var context = container.Resolve<IGeneralContext>())
{
    var nc = new Cliente() { };
    context.Clientes.Add(nc);
    // ...
}

如果不可能将所有这些存储库属性放在上下文中本身,您可能想创建一个包装器对象:

using (var context = container.Resolve<NorthwindContext>())
{
    var nc = new Cliente() { };
    context.ClienteRepository.Add(nc);

    // ...
}

public class NorthwindContext
{
    private IGeneralContext context;
    private IRepositoryFactory repFactory;

    public NorthwindContext(IGeneralContext context,
        IRepositoryFactory repFactory)
    {
        this.context = context;
        this.repFactory = repFactory;
    }

    public IClienteRepository Clientes
    {
        get { return this.repFactory
            .Create<IClienteRepository>(this.context); }
    }

    public IOrderRepository Orders
    {
        get { return this.repFactory
            .Create<IOrderRepository>(this.context); }
    }

    public void CommitChanges()
    {
        this.context.CommitChanges();
    }
}

您还可能想尝试最小化对容器的调用量。尝试通过构造函数注入尽可能多的内容。

这是一个有趣的问题关于工作单元模式(=上下文)和可能有用的存储库。

我希望这有帮助。

You might want to take a step back and look at your design. I found out that most of the time I thought I needed some complex DI configuration, the problem was actually in my design. Here are a few options you could consider:

1) Use a factory for creating repositories and supply the context to that factory:

var repositoryFactory = container.Resolve<IRepositoryFactory>();

using (var context = container.Resolve<IGeneralContext>())
{
    var rep = repositoryFactory.Create<IClienteRepository>(context);
    // ...
}

public class RepositoryFactory : IRepositoryFactory
{
    public TRepository Create<TRepository>(IGeneralContext context)
        where TRepository : IRepository
    {
        var repository = Container.Resolve<TRepository>();
        repository.Context = context;
        return repository;
    }
}

2) Try making the repositories part of the context:

using (var context = container.Resolve<IGeneralContext>())
{
    var nc = new Cliente() { };
    context.Clientes.Add(nc);
    // ...
}

If it is not possible to put all those repository properties on the context itself, you might want to create a wrapper object:

using (var context = container.Resolve<NorthwindContext>())
{
    var nc = new Cliente() { };
    context.ClienteRepository.Add(nc);

    // ...
}

public class NorthwindContext
{
    private IGeneralContext context;
    private IRepositoryFactory repFactory;

    public NorthwindContext(IGeneralContext context,
        IRepositoryFactory repFactory)
    {
        this.context = context;
        this.repFactory = repFactory;
    }

    public IClienteRepository Clientes
    {
        get { return this.repFactory
            .Create<IClienteRepository>(this.context); }
    }

    public IOrderRepository Orders
    {
        get { return this.repFactory
            .Create<IOrderRepository>(this.context); }
    }

    public void CommitChanges()
    {
        this.context.CommitChanges();
    }
}

You also might want to try minimizing the amount of calls to the container. Try to inject as much as you can through the constructor.

Here is an interesting SO question about the Unit of Work pattern (= context) and repositories that might be helpful.

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文