依赖注入 C# 每次都获取可枚举的新实例

发布于 2025-01-13 03:41:00 字数 665 浏览 0 评论 0原文

我有一个实现接口的类列表,如下所示:

pulic interface ISample 
{
 public int Id { get; set; }
}
pulic class SampleA : ISample {}
pulic class SampleB : ISample {}
pulic class SampleC : ISample {}

这些类的生命周期是瞬态的。 我为创建的实例创建一个包装器,如下所示:

public class Wrapper
{
   private IEnumerable<ISample> _Samples;
   public Wrapper(IEnumerable<ISample> Samples)
   {
      _Samples = Samples;
   }

   public void InstanceGenerator(int Id)
   {
     ISample MySample = _Samples.FirstOrDefault(s => s.Id == Id);
     //do somethings...
   }
}

包装器类的生命周期是单例的。我希望每次调用“InstanceGenerator”时,它都会创建一个新实例,但它只创建一个实例,并且每次都会返回该实例。

I have a list of class that implement an interface, like this:

pulic interface ISample 
{
 public int Id { get; set; }
}
pulic class SampleA : ISample {}
pulic class SampleB : ISample {}
pulic class SampleC : ISample {}

Life time of these classs are Transient.
I create a wrapper for created instances, like this:

public class Wrapper
{
   private IEnumerable<ISample> _Samples;
   public Wrapper(IEnumerable<ISample> Samples)
   {
      _Samples = Samples;
   }

   public void InstanceGenerator(int Id)
   {
     ISample MySample = _Samples.FirstOrDefault(s => s.Id == Id);
     //do somethings...
   }
}

Life time of Wrapper class is singleton. I would like that every time that I call "InstanceGenerator", it creates a new instance but it only creates one instance and every time returns that.

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

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

发布评论

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

评论(1

扮仙女 2025-01-20 03:41:00

您需要创建一个工厂来在方法调用中创建新实例,而不是直接注册类型。

以下示例基于您的代码,但也显示了一些差异。除了 ISample 实现和包装器之外,还在 DI 容器中注册了一个工厂。它定义了一个 GenerateSamples 方法,该方法在调用时使用服务提供程序创建新实例:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddTransient<ISample, SampleA>();
builder.Services.AddTransient<ISample, SampleB>();
builder.Services.AddSingleton<Wrapper>();
builder.Services.AddSingleton<SampleFactory>();

var app = builder.Build();

var wrapper = app.Services.GetRequiredService<Wrapper>();
wrapper.InstanceGenerator();
wrapper.InstanceGenerator();

class Wrapper
{
    private readonly SampleFactory _factory;

    public Wrapper(SampleFactory factory)
    {
        _factory = factory;
    }

    public void InstanceGenerator()
    {
        var samples = _factory.GenerateSamples();
        foreach(var sample in samples)
            Console.WriteLine($"Type: {sample.GetType().Name}, Id: {sample.InstanceId}");
    }
}

class SampleFactory
{
    private readonly IServiceProvider _serviceProvider;

    public SampleFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IEnumerable<ISample> GenerateSamples()
    {
        return _serviceProvider.GetRequiredService<IEnumerable<ISample>>();
    }
}

interface ISample { public Guid InstanceId { get; }}

class SampleA : ISample { public Guid InstanceId { get; set; } = Guid.NewGuid(); }
class SampleB : ISample { public Guid InstanceId { get; set; } = Guid.NewGuid(); }

如果运行该示例,您可以检查 InstanceId 来验证是否使用了新实例每次都在 InstanceGenerator 方法中。

Instead of registering the types directly, you'd need to create a factory that creates new instances in a method call.

The following sample is based on your code, but also shows some differences. In addition to the ISample implementations and the wrapper, a factory is registered in the DI container. It defines a GenerateSamples method that uses the service provider to create new instances when called:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddTransient<ISample, SampleA>();
builder.Services.AddTransient<ISample, SampleB>();
builder.Services.AddSingleton<Wrapper>();
builder.Services.AddSingleton<SampleFactory>();

var app = builder.Build();

var wrapper = app.Services.GetRequiredService<Wrapper>();
wrapper.InstanceGenerator();
wrapper.InstanceGenerator();

class Wrapper
{
    private readonly SampleFactory _factory;

    public Wrapper(SampleFactory factory)
    {
        _factory = factory;
    }

    public void InstanceGenerator()
    {
        var samples = _factory.GenerateSamples();
        foreach(var sample in samples)
            Console.WriteLine(
quot;Type: {sample.GetType().Name}, Id: {sample.InstanceId}");
    }
}

class SampleFactory
{
    private readonly IServiceProvider _serviceProvider;

    public SampleFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IEnumerable<ISample> GenerateSamples()
    {
        return _serviceProvider.GetRequiredService<IEnumerable<ISample>>();
    }
}

interface ISample { public Guid InstanceId { get; }}

class SampleA : ISample { public Guid InstanceId { get; set; } = Guid.NewGuid(); }
class SampleB : ISample { public Guid InstanceId { get; set; } = Guid.NewGuid(); }

If you run the sample, you can check the InstanceId to verify that a new instance is used in the InstanceGenerator method every time.

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