Преимущество использования интерфейса в качестве сервисного контракта в WCF

Я ищу право написать, почему мы должны использовать интерфейс в качестве контракта на обслуживание в WCF. я получил этот URL Почему.NET WCF Service требует Интерфейс, и отсюда я узнал, что мы можем написать атрибут контракта сервиса на классе вместо интерфейса.

[ServiceContract]
public class TheService
{
   // more stuff here
}

запись конфигурации

<services>
    <service name="YourServiceName">
        <endpoint address="" behaviorConfiguration="httpBehavior" binding="webHttpBinding" contract="TheService"/>
    </service>
</services>

но очень разочарован тем, что не получил все веские основания, например, почему люди часто используют интерфейс в качестве контракта на обслуживание?

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

1 ответ

Решение

Как вы продемонстрировали - вам не нужно определять интерфейс для контракта на обслуживание, чтобы он работал. Тем не менее, спорный в этом вопросе, ваш класс нарушает принцип Единой Ответственности (если это официально является ОО-принципом - но, по моему мнению, это один из тех универсальных принципов, которые, кажется, являются хорошей идеей везде).

Контракт на обслуживание действует как "контракт" (дух!) Между издателем сервиса и клиентами, которые его используют. Таким образом, как только у вас есть клиенты, потребляющие его, вы должны быть очень осторожны с любыми изменениями, которые вы вносите, особенно если клиенты могут быть третьими лицами, над которыми вы не имеете никакого контроля. В соответствии с "Принципом единой ответственности", определение интерфейса, представляющего контракт, позволяет предоставить этому интерфейсу ответственность за открытый API, отделяя его от реализации.

[ServiceContract]
public interface ILoggingService
{
    [OperationContract]
    void LogMessage(string message);    
}

Эта реализация основана на том факте, что все клиенты подключаются к одному и тому же экземпляру:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class SingletonLoggingService : ILoggingService
{
    void LogMessage(string message)
    {

    }

}

Эта реализация дает вам новый экземпляр сервиса для каждого обращения к нему:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class SingletonLoggingService : ILoggingService
{
    void LogMessage(string message)
    {

    }

}

Преимущество интерфейса в том, что я могу возиться с реализацией сколько угодно (включая режим создания экземпляров, параллелизм, поведение в сеансах клиента, пространство имен, имя класса и т. Д.), И мне не нужно беспокоиться что я потенциально ломаю любых клиентов.

Согласовано - есть способы поддерживать обратную совместимость, даже если вы определяете сервисный контракт как класс - но это гораздо более подвержено ошибкам, и вы, скорее всего, что-то забудете. Разделение общедоступного API и его реализации приводит к более чистому коду и меньшему риску ошибок разработчиков.

Другие вопросы по тегам