C # приведение конкретных переменных класса во время выполнения (Dependency Injection) - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь внедрить внедрение зависимостей в моем проекте для подключения к SQL-серверу для модульного тестирования. Я использовал встроенные абстрактные классы, входящие в библиотеку SQL, и создал свои собственные классы Mock для SqlCommand, SqlConnection и SqlTransaction. Ниже приведены мои классы.

Я не могу использовать метод свойства SqlCommand (SqlParameterCollection), который во время компиляции назван как AddWithValue в моем файле program.cs.

Я получаю нижеошибка

«DbParameterCollection» не содержит определения для «AddWithValue», и нет доступного метода расширения «AddWithValue», принимающего первый аргумент типа «DbParameterCollection» (вы пропустили директиву using илиссылка на сборку?)

Объект DbParameterCollection находится в абстрактном классе DbCommand, однако данный объект, имеющий метод AddWithValue, находится в конкретном классе, который является SqlCommand.

Как я могу сказать компиляторучто метод AddWithValue должен вызываться для свойства класса SqlCommand, а не для DBCommand.

Вот все мои классы.

Поскольку я новичок в этом, я не нашел ничего, вводящего конкретныеклассы во время выполнения с использованием отражения или могут быть некоторые другие способысделать это.

SQLWrapper.cs

namespace DAL
{
    public class SQLWrapper
    {
        private Context _ctx;
        private string _referenceID;
        private string _connectionKey;
        private static string _connectionString;
        private int _timeout = 180;

        public SQLWrapper(Context ctx, string referenceID, string connectionKey)
        {
            _ctx = ctx;
            _referenceID = referenceID;
            _connectionKey = connectionKey;
        }

        public async Task<Error> GetConnectingStringAsync()
        {
           // Gets the connection string from config
        }

        /// <summary>
        /// Executes the statement.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        public async Task<Error> ExecuteStatementAsync()
        {
            Error error = null;
            try
            {
                error = await GetConnectingStringAsync();
                if (error != null)
                {
                    return error;
                }

                using (_ctx.connection)
                {
                    _ctx.connection.ConnectionString = _connectionString;
                    _ctx.command.CommandTimeout = _timeout;
                    try
                    {
                        await _ctx.connection.OpenAsync();
                        _ctx.command.Connection = _ctx.connection;
                        _ctx.command.Prepare();
                        _ctx.transaction = _ctx.connection.BeginTransaction();
                        await _ctx.command.ExecuteNonQueryAsync();
                        _ctx.transaction.Commit();
                        return null;
                    }
                    catch (Exception ex)
                    {
                        if (_ctx.transaction != null)
                        {
                            _ctx.transaction.Rollback();
                        }
                        return error;
                    }
                }
            }
            catch (Exception ex)
            {
                return error;
            }
        }        
    }
}

MockCommand.cs

namespace DAL
{
    class MockCommand : DbCommand
    {
        private string _commandText;
        private int _commandTimeout;
        private DbConnection _DbConnection;

        public MockSQL Connection { get; set; }
        public override string CommandText { get => _commandText; set => _commandText = value; }
        public override int CommandTimeout { get => _commandTimeout; set => _commandTimeout = value; }
        public override CommandType CommandType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public override bool DesignTimeVisible { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public override UpdateRowSource UpdatedRowSource { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        protected override DbConnection DbConnection { get => _DbConnection; set => _DbConnection = value; }

        new public SqlParameterCollection Parameters { get; }
        protected override DbParameterCollection DbParameterCollection => null;

        protected override DbTransaction DbTransaction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public override void Cancel()
        {
            throw new NotImplementedException();
        }

        public override int ExecuteNonQuery()
        {
            return 0;
        }

        public override object ExecuteScalar()
        {
            throw new NotImplementedException();
        }

        public override void Prepare()
        {
            return;
        }

        protected override DbParameter CreateDbParameter()
        {
            throw new NotImplementedException();
        }

        protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
        {
            throw new NotImplementedException();
        }
    }
}

MockSQL.cs

namespace DAL
{
    class MockSQL : DbConnection
    {
        private string _connectionString;
        public override string ConnectionString { get => ""; set => _connectionString = value; }

        public override string Database => throw new NotImplementedException();

        public override string DataSource => throw new NotImplementedException();

        public override string ServerVersion => throw new NotImplementedException();

        public override ConnectionState State => throw new NotImplementedException();

        public override void ChangeDatabase(string databaseName)
        {
            throw new NotImplementedException();
        }

        public override void Close()
        {
            throw new NotImplementedException();
        }

        public override void Open()
        {
            return;
        }

        protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
        {
            return new MockTransaction();
        }

        protected override DbCommand CreateDbCommand()
        {
            throw new NotImplementedException();
        }
    }
}

MockTransaction.cs

namespace DAL
{
    class MockTransaction : DbTransaction
    {
        public override IsolationLevel IsolationLevel => throw new NotImplementedException();

        protected override DbConnection DbConnection => throw new NotImplementedException();

        public override void Commit()
        {
            return;
        }

        public override void Rollback()
        {
            throw new NotImplementedException();
        }
    }
}

Context.cs

 public class Context
    {
        public DbConnection connection;
        public DbCommand command;
        public DbTransaction transaction;
        public ICongigRPC config;
    }

ContextInitializer.cs

public static class ContextInitializer
    {
        public static Context InitCtx()
        {
            return new Context()
            {
                connection = new SqlConnection(),
                command = new SqlCommand(),
                transaction = null
            };
        }
    }

Program.cs

Context ctx = MockContextInitializer.MockInitCtx();
            ctx.command.CommandText = "SELECT * FROM MEMBERMAPPING WHERE OldMemberID = @OldMemberID;";
            ctx.command.Parameters.AddWithValue("@OldMemberID", "1234");
            SQLWrapper wrapper = new SQLWrapper(ctx, "123", "123");
            wrapper.ExecuteStatementAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...