Инъекция зависимости в единицу работы - PullRequest
0 голосов
/ 04 июня 2018

У меня проблема, моя unitofwork не создает экземпляр AppSettings всякий раз, когда он вызывается.Unitofwork для моего уровня данных репозитория.

Эта ошибка появляется:

Произошло необработанное исключение при обработке запроса.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта.Core.UnitOfWork..ctor () в UnitOfWork.cs, строка 24

Stack Query Cookies Заголовки NullReferenceException: Ссылка на объект не установлена ​​на экземпляр объекта.Core.UnitOfWork..ctor () в UnitOfWork.cs + _connection = new SqlConnection (App.GetConnectionString ());Core.Service.UserService.Login (сущность пользователя) в UserService.cs + с использованием (var uow = new UnitOfWork (/ connStr /)) SRTManagement.Controllers.LoginController + d__6.MoveNext () в LoginController.cs+ var _user = service.Login (пользователь);

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);
        }
    }
}

1 Ответ

0 голосов
/ 04 июня 2018

IAppSettings не вводится в ваш UnitOfWork, поэтому при вызове он будет нулевым

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
}

Предполагается, что UnitOfWork также зарегистрирован в коллекции услуг.

public void ConfigureServices(IServiceCollection services) {
    services.AddTransient<IAppSettings, AppSettings>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();
    services.AddMvc();
}

Я бы также предложил переосмыслить текущий дизайн и избегать тесной связи UoW с проблемами реализации, такими как SqlConnection.

Если вы остаетесь с ADO, тогда рассмотрите возможность использования абстракции IDbConnectionFactory.

public class MyDbConnectionFactory : IDbConnectionFactory {
    private readonly IAppSettings appSettings;

    public MyDbConnectionFactory(IAppSettings appSettings) {
        this.appSettings = appSettings;
    }

    public IDbConnection CreateConnection() {
        return new SqlConnection(appSettings.GetConnectionString());
    }
}

Что позволило бы реорганизовать UoW на

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
}

При обычной регистрации службы

public void ConfigureServices(IServiceCollection services) {
    services.AddTransient<IAppSettings, AppSettings>();
    services.AddTransient<IDbConnectionFactory, MyDbConnectionFactory>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();
    services.AddMvc();
}
...