Я пытаюсь внедрить внедрение зависимостей в моем проекте для подключения к 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();