WCF с разделяемой интерфейсной сборкой
От: Аноним  
Дата: 15.11.10 17:07
Оценка:
Обычно WCF делался так — в сборке публиковались интерфейсы, определялись атрибуты [ServiceContract], [DataContract] и так далее, писалась реализация, после чего откомпилированная сборка шла в svcutil, оттуда выдавались классы, которые можно было инстанцировать из клиента.

А можно ли сделать разделяемую сборку, в которой опубликовать все интерфейсы, чтобы и клиент и сервер ссылались на эту сборку и использовали один набор интерфейсов для работы, а не прокси-заменитель?
Re: WCF с разделяемой интерфейсной сборкой
От: RushDevion Россия  
Дата: 15.11.10 17:13
Оценка: 1 (1)
Ключ /reference для svcutil смотрите.
В самой студии на вкладке генерации прокси есть галка Use types in refrenced assemblies.
А можно вообще без генерации прокси обойтись, если строить канал через ChanellFactory (нужны будут только интерфейсы).
Re: WCF с разделяемой интерфейсной сборкой
От: anton_t Россия  
Дата: 15.11.10 17:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Обычно WCF делался так — в сборке публиковались интерфейсы, определялись атрибуты [ServiceContract], [DataContract] и так далее, писалась реализация, после чего откомпилированная сборка шла в svcutil, оттуда выдавались классы, которые можно было инстанцировать из клиента.


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


Можно. Что-то типа:

ICalculator.cs
using System.ServiceModel;

namespace WcfExample.Contracts
{
    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double a, double b);
    }
}


MyCloudCalculator.cs
using WcfExample.Contracts;

namespace WcfExample.Service
{
    public class MyCloudCalculator : ICalculator
    {
        public double Add(double a, double b)
        {
            return a + b;
        }
    }
}


Program.cs на сервере:
using System;
using System.ServiceModel;

namespace WcfExample.Service
{
    class Program
    {
        static int Main(string[] args)
        {
            try
            {
                var host = new ServiceHost(typeof (MyCloudCalculator));
                host.Open();
                Console.WriteLine("Started");
                Console.ReadLine();
                return 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.ReadLine();
                return -1;
            }
        }
    }
}



Program.cs на клиенте:
using System;
using System.ServiceModel;
using WcfExample.Contracts;

namespace WcfExample.Client
{
    class Program
    {
        static int Main(string[] args)
        {
            try
            {
                var channelFactory = new ChannelFactory<ICalculator>("CalculatorEndpoint");
                var client = channelFactory.CreateChannel();
                var result = client.Add(1, 2);
                Console.WriteLine("Result = {0}", result);
                Console.ReadLine();
                return 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.ReadLine();
                return -1;
            }
        }
    }
}


Солить App.config-и по вкусу.
Re[2]: WCF с разделяемой интерфейсной сборкой
От: Аноним  
Дата: 15.11.10 17:59
Оценка:
Здравствуйте, anton_t, Вы писали:

_>Здравствуйте, Аноним, Вы писали:



Да, я только что по наводке RushDevion написал аналогичную вещь, только воспользовался статической фабрикой

var channel = ChannelFactory<IWhatever>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(@"net.pipe://localhost/whatever"));


Спасибо за код.

Кстати, как лучше поступить? Держать открытой фабрику, создавая у нее каналы по мере надобности, создавать каналы через статический метод, или же вообще удерживать инстанс канала насколько это возможно? Приложение не нагруженное, но не хотелось бы тормозов из-за ерунды.
Re[2]: WCF с разделяемой интерфейсной сборкой
От: Аноним  
Дата: 15.11.10 18:04
Оценка:
Здравствуйте, RushDevion, Вы писали:

RD>Ключ /reference для svcutil смотрите.

RD>В самой студии на вкладке генерации прокси есть галка Use types in refrenced assemblies.
RD>А можно вообще без генерации прокси обойтись, если строить канал через ChanellFactory (нужны будут только интерфейсы).

Нужно ли в случае постройки канала через фабрику специфицировать дата-контракты? В тестовом примере


    [ServiceContract]
    public interface IWhatever
    {
        [OperationContract]
        DataMessage Do(DataMessage what);
    }

    public class DataMessage
    {
        public string Message { get; set; }
    }


    public class Whatever : IWhatever
    {
        public DataMessage Do(DataMessage what) { return new DataMessage() { Message = what.Message + " DONE" }; }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(Whatever), new Uri(@"net.pipe://localhost/whatever")))
            {
                host.Open();
                Thread t = new Thread(RCV);
                t.Start();
                Console.ReadLine();
            }
        }

        static void RCV()
        {
            var channel = ChannelFactory<IWhatever>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(@"net.pipe://localhost/whatever"));
            Console.WriteLine(channel.Do(new DataMessage() { Message = "SHIT" }).Message);
        }
    }


Заработало и без них.
Re[3]: WCF с разделяемой интерфейсной сборкой
От: RushDevion Россия  
Дата: 15.11.10 19:39
Оценка:
А>Кстати, как лучше поступить? Держать открытой фабрику, создавая у нее каналы по мере надобности, создавать каналы через статический метод, или же вообще удерживать инстанс канала насколько это возможно? Приложение не нагруженное, но не хотелось бы тормозов из-за ерунды.

Конструирование фабрики — довольно затратная операция — лучше ее переиспользовать по возможности.
Вот здесь посмотрите подробнее на этот счет.

> Нужно ли в случае постройки канала через фабрику специфицировать дата-контракты? В тестовом примере

> Заработало и без них.

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