I'm having an issue my unitofwork doesn't create instance of AppSettings whenever it is called. Unitofwork is for my repository data layer.
This error comes out:
An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object. Core.UnitOfWork..ctor() in UnitOfWork.cs, line 24
Stack Query Cookies Headers NullReferenceException: Object reference not set to an instance of an object. Core.UnitOfWork..ctor() in UnitOfWork.cs + _connection = new SqlConnection(App.GetConnectionString()); Core.Service.UserService.Login(User entity) in UserService.cs + using (var uow = new UnitOfWork(/ connStr /)) SRTManagement.Controllers.LoginController+d__6.MoveNext() in LoginController.cs + var _user = service.Login(user);
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IAppSettings,AppSettings>();
services.AddMvc();
}
IAppSettings.cs
namespace Core.Etc
{
public interface IAppSettings
{
string GetConnectionString();
}
}
AppSettings.cs
namespace Core.Etc
{
public class AppSettings : IAppSettings
{
public readonly string _connectionString;
public AppSettings(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection");
}
public string GetConnectionString()
{
return _connectionString;
}
}
}
UnitOfWork.cs
namespace Core
{
public class UnitOfWork : IUnitOfWork
{
private IDbConnection _connection;
private IDbTransaction _transaction;
private IUserRepository _user;
private IRoleRepository _role;
private IAppSettings App;
private bool _disposed;
private bool _token;
public UnitOfWork()
{
_connection = new SqlConnection(App.GetConnectionString());
_connection.Open();
_transaction = _connection.BeginTransaction();
_token = false;
}
public IUserRepository UserRepository
{
get { return _user ?? (_user = new UserRepository(_transaction)); }
}
public IRoleRepository RoleRepository
{
get { return _role ?? (_role = new RoleRepository(_transaction)); }
}
public bool Success()
{
return _token;
}
public void Commit()
{
try
{
_transaction.Commit();
_token = true;
}
catch
{
_transaction.Rollback();
_token = false;
throw;
}
finally
{
_transaction.Dispose();
_transaction = _connection.BeginTransaction();
ResetRepositories();
}
}
private void ResetRepositories()
{
_user = null;
_role = null;
App = null;
}
public void Dispose()
{
DisposeConn(true);
GC.SuppressFinalize(this);
}
private void DisposeConn(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if(_transaction != null)
{
_transaction.Dispose();
_transaction = null;
}
if(_connection != null)
{
_connection.Dispose();
_connection = null;
}
}
_disposed = true;
}
}
~UnitOfWork()
{
DisposeConn(false);
}
}
}
IAppSettings
is not being injected into your UnitOfWork
, so it will be null when call as you have it
public class UnitOfWork : IUnitOfWork {
private IDbConnection _connection;
private IDbTransaction _transaction;
private IUserRepository _user;
private IRoleRepository _role;
private IAppSettings App;
private bool _disposed;
private bool _token;
public UnitOfWork(IAppSettings App) {
this.App = App;
_connection = new SqlConnection(App.GetConnectionString());
_connection.Open();
_transaction = _connection.BeginTransaction();
_token = false;
}
//Remove the rest of the code for brevity
}
Assuming UnitOfWork
is also registered with the service collection.
public void ConfigureServices(IServiceCollection services) {
services.AddTransient<IAppSettings, AppSettings>();
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddMvc();
}
I would also suggest rethinking the current design and avoid tightly coupling the UoW to implementation concerns like SqlConnection
.
If staying with ADO then consider using a IDbConnectionFactory
abstraction.
public class MyDbConnectionFactory : IDbConnectionFactory {
private readonly IAppSettings appSettings;
public MyDbConnectionFactory(IAppSettings appSettings) {
this.appSettings = appSettings;
}
public IDbConnection CreateConnection() {
return new SqlConnection(appSettings.GetConnectionString());
}
}
Which would let the UoW to be refactored to
public class UnitOfWork : IUnitOfWork {
private IDbConnection _connection;
private IDbTransaction _transaction;
private IUserRepository _user;
private IRoleRepository _role;
private bool _disposed;
private bool _token;
public UnitOfWork(IDbConnectionFactory factory) {
_connection = factory.CreateConnection();
_connection.Open();
_transaction = _connection.BeginTransaction();
_token = false;
}
//Remove the rest of the code for brevity
}
With usual service registrations
public void ConfigureServices(IServiceCollection services) {
services.AddTransient<IAppSettings, AppSettings>();
services.AddTransient<IDbConnectionFactory, MyDbConnectionFactory>();
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddMvc();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.