Я пытаюсь написать код, помогающий тестировать службы WCF. Доступ к этим службам осуществляется через класс фасадов, который создает экземпляр прокси, затем вызывает метод прокси и возвращает результат; для каждого метода прокси. Я хотел бы иметь возможность заменить текущий код создания тем, что либо создает реальный сервис, либо поддельный.Общие ограничения и наследование
Я не мог заставить это работать. Я варил вниз к следующему:
using System.ServiceModel;
namespace ExpressionTrees
{
public interface IMyContract
{
void Method();
}
public class MyClient : ClientBase<IMyContract>, IMyContract
{
public MyClient()
{
}
public MyClient(string endpointConfigurationName)
: base(endpointConfigurationName)
{
}
public void Method()
{
Channel.Method();
}
}
public class Test
{
public TClient MakeClient<TClient>()
where TClient : ClientBase<IMyContract>, IMyContract, new()
{
return new MyClient("config");
// Error:
// Cannot convert expression of type 'ExpressionTrees.ServiceClient' to return type 'TClient'
}
}
}
Почему, несмотря на то, MyClient
класс является производным от ClientBase<IMyContract>
и реализует IMyContract
, что я не могу вернуть MyClient
экземпляр из метода означало вернуть TClient
? TClient
указывает ограничение типа, которое, как я думал, означало одно и то же.
Моя цель состояла в том, чтобы вызывать код как это:
public void CallClient<TClient>()
where TClient : ClientBase<IMyContract>, IMyContract
{
TClient client = null;
bool success = false;
try
{
client = MakeClient<TClient>();
client.Method();
client.Close();
success = true;
}
finally
{
if (!success && client != null)
{
client.Abort();
}
}
}
Но вместо того, чтобы всегда называя MakeClient<TClient>
, я хотел, чтобы быть в состоянии иметь тестовый модуль впрыснуть фиктивного объекта. Поскольку код выше зависит как от ClientBase<IMyContract>
, IMyContract
, кажется, я пытался «синтезировать» общий класс, который бы удовлетворял этому ограничению.
В ретроспективе это не имеет смысла. Например, ClientBase<IMyContract>
будет создан таким образом, чтобы был создан объект Channel
, который затем мог бы делегировать метод Close
.
Я наткнулся на то, что тот же самый код работает как для реального, так и для поддельных сервисов. Теперь я ввожу IMyService
и вызывая IMyService.Method
или client.Method
в зависимости от того, является ли мое введенное свойство нулевым.
Я до сих пор не могу представить, почему этот вопрос привлекает вниз. Хотел бы, чтобы один из нижеперечисленных сказал мне, чтобы я мог улучшить вопрос. –