当私有构造函数有参数时创建singleton



我想在StudentProvider中实现singleton模式,然后通过接口访问方法。StudentProvider构造函数接受的参数很少。以下是没有singleton的示例工作代码。

public interface IStudentProvider
{
Task<StudentViewModel> GetStudentAsync();
}
public class StudentProvider : IStudentProvider
{
private readonly HttpContext httpContext;
private readonly IActionContextAccessor actionContextAccessor;
private readonly IConfiguration configuration;
private readonly IUnitOfWork unitOfWork;
private readonly string host;
public StudentProvider(IHttpContextAccessor _httpContextAccessor, IActionContextAccessor _actionContextAccessor, IConfiguration _configuration, IUnitOfWork _unitOfWork)
{
httpContext = _httpContextAccessor.HttpContext;

actionContextAccessor = _actionContextAccessor;
configuration = _configuration;
unitOfWork = _unitOfWork;
host = _httpContextAccessor.HttpContext.Request.Host.Host;
}
public async Task<StudentViewModel> GetStudentAsync()
{
var std = new StudentViewModel();
// httpContext, actionContextAccessor, configuration, unitOfWork and host uses here
return std;
}
}

现在我将其转换为单个,代码如下:

public interface IStudentProvider
{
Task<StudentViewModel> GetStudentAsync();
}
public sealed class StudentProvider : IStudentProvider
{
private readonly HttpContext httpContext;
private readonly IActionContextAccessor actionContextAccessor;
private readonly IConfiguration configuration;
private readonly IUnitOfWork unitOfWork;
private readonly string host;
private static StudentProvider instance = null;
public static StudentProvider GetInstance
{
get
{
if (instance == null)
{
instance = new StudentProvider();
}
return instance;
}
}
private StudentProvider(IHttpContextAccessor _httpContextAccessor, IActionContextAccessor _actionContextAccessor, IConfiguration _configuration, IUnitOfWork _unitOfWork)
{
httpContext = _httpContextAccessor.HttpContext;
actionContextAccessor = _actionContextAccessor;
configuration = _configuration;
unitOfWork = _unitOfWork;
host = _httpContextAccessor.HttpContext.Request.Host.Host;
}
public async Task<StudentViewModel> GetStudentAsync()
{
var std = new StudentViewModel();
// httpContext, actionContextAccessor, configuration, unitOfWork and host uses here
return std;
}
}

上面的单例代码的问题是instance = new StudentProvider();期望的参数是我无法传递的

如何从singleton实例向构造函数传递参数?

您似乎在使用ASP。NET及其依赖项注入。如果是这样,您可以使用AddSingleton来注册您的提供者,而不是实现您自己的单例模式。辛格尔顿。

顺便说一句,您的提供者依赖于HttpContext,这意味着您需要为不同的请求创建不同的实例。

正如@Jon Skeet所建议的,使用依赖注入会更好。

我也会推荐@XiaofengZheng解决方案使用带有工厂模式的单例依赖注入。

若所有这些都不能满足,你们可以使用下面的解决方案。

您需要将IServiceProvider的引用作为singleton保存在您的启动文件中,该文件可以全局访问。

public class Startup
{
public static IServiceProvider ServiceProvider { get; private set; }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider) {
...
ServiceProvider = serviceProvider;
}
}

然后,您可以访问"启动"。StudentProvider中的ServiceProvider来创建其他依赖项的实例。

using Microsoft.Extensions.DependencyInjection;
public sealed class StudentProvider : IStudentProvider
{
private readonly HttpContext httpContext;
private readonly IActionContextAccessor actionContextAccessor;
private readonly IConfiguration configuration;
private readonly IUnitOfWork unitOfWork;
private readonly string host;
private static StudentProvider instance = null;
public static StudentProvider GetInstance
{
get
{
if (instance == null)
{
instance = new StudentProvider(
Startup.ServiceProvider.GetService<IHttpContextAccessor>(), 
Startup.ServiceProvider.GetService<IActionContextAccessor>(), 
Startup.ServiceProvider.GetService<IConfiguration>(), 
Startup.ServiceProvider.GetService<IUnitOfWork>()
);
}
return instance;
}
}
private StudentProvider(IHttpContextAccessor _httpContextAccessor, IActionContextAccessor _actionContextAccessor, IConfiguration _configuration, IUnitOfWork _unitOfWork)

}

最新更新