Castle Windsor WCF Регистрация обслуживания клиентов на основе соглашения - PullRequest
1 голос
/ 28 января 2011

У меня есть клиент-серверное приложение, которое взаимодействует через WCF.Оба они также используют Castle Windsor для разрешения зависимостей.

Моя цель - полностью избежать необходимости регистрировать конечные точки сервера или клиента WCF.Я достиг серверной стороны путем 'соглашения', используя следующий код

// registers all services which implement exactly 1 [ServiceContract]
_windsorContainer.Register(
AllTypes.FromThisAssembly().IncludeNonPublicTypes().Where(
    t => 1 == (from i in t.GetInterfaces() where i.IsDefined(typeof(ServiceContractAttribute), true) select i).Count())
    .Configure(c => c.LifeStyle.PerWcfSession()
    .ActAs(new DefaultServiceModel().AddEndpoints(
         WcfEndpoint.BoundTo(new NetTcpBinding())
             .At("net.tcp://" + LocalAddress.ToString() + ":7601/" + c.ServiceType.Name),
         WcfEndpoint.FromEndpoint(new UdpDiscoveryEndpoint())
            ))

    ).WithService.Select(
    (Type type, Type[] baseTypes) => from i in type.GetInterfaces() where i.IsDefined(typeof(ServiceContractAttribute), true) select i
    )
);

. Этот код найдет все классы в текущей сборке и любые классы, которые реализуют интерфейс контракта на обслуживание (идентифицируемый атрибутом ServiceContract) будет зарегистрирован (с обнаружением UDP) по адресу "net.tcp: // localhost: 7601 / [service-contract-interface-name]".

Теперь я просто хочу на стороне клиентауравнение.

Как правило, чтобы использовать Castle для генерации прокси-клиентов для контрактов WCF, будет работать следующий код:

var model = new DefaultClientModel
{
    Endpoint = WcfEndpoint.ForContract<IServiceContract>().BoundTo(new NetTcpBinding()).Discover(typeof(IServiceContract))
};

container.Register(
    Component.For<ChannelReconnectPolicy>(),
    Castle.Facilities.WcfIntegration.WcfClient.ForChannels(model),
);

Я хочу, чтобы Castle выполнял такого родарегистрация для всех интерфейсов «сервис-контракт» в данной сборке - однако помощник AllTypes, похоже, возвращает только классы, а не интерфейсы (что, я думаю, делает его «AllClasses», а не «AllTypes»!) ... Может ли Касл сделать этои какой синтаксис?Кшиштоф?(помогите!)

Спасибо!

1 Ответ

1 голос
/ 17 сентября 2011

Извините за столь поздний ответ - жизнь разработчика никогда не бывает спокойной!

Я выкопал код, и он не такой «лаконичный», как мне бы хотелось, возможно, кто-то может взглянуть на интеграцию чего-то подобного в Castle… но здесь идет ...

// these are all the namespaces that will be scanned for WCF service contracts
string[] remoteServiceNamespaces 
    = new string[] { "MyContracts.Services", "Interlinq" };

// everything from here on is in the Castle DLLs (all the types)
List<IRegistration> clientContractRegistrations = new List<IRegistration>();
foreach (
    var interfaceContract in
    (from s in remoteServiceNamespaces
    select (from i in Assembly.LoadWithPartialName(s).GetTypes()
        where i.IsInterface
        && 
        i.IsDefined(typeof(ServiceContractAttribute), false)
        select i)).SelectMany( x => x )
    )
{
    ServiceContractAttribute attr 
        = Attribute.GetCustomAttribute(
                    interfaceContract, 
                    typeof(ServiceContractAttribute)) 
                    as ServiceContractAttribute;
    if (null != attr)
    {
    WcfClientModelBase model = null;

    // here we handle the case of the service being duplex...
    if (null != attr.CallbackContract)
    {
        model = new DuplexClientModel
        {
        // All the automatically registered services will use NetTcp, 
        // and will discover their addresses (you could use binding 
        // inference aswell if you liked)
        // here I have a method called 'CreateNetTcpBinding' which 
        // creates my custom binding that ALL my services use.
        Endpoint = 
                 WcfEndpoint.ForContract(interfaceContract)
                 .BoundTo(CreateNetTcpBinding())
                 .Discover(interfaceContract)
                 .PreferEndpoint(list => list[0])
        }.Callback(_windsor.Resolve(attr.CallbackContract));
    }
    else
    {
        model = new DefaultClientModel
        {
        Endpoint = WcfEndpoint.ForContract(interfaceContract)
                    .BoundTo(new NetTcpBinding())
                    .Discover(interfaceContract)
                    .PreferEndpoint(list => list[0])
        };
    }
    clientContractRegistrations.Add(WcfClient.ForChannels(model));
    }
}

// now that we've built our registration list, let's actually register 
// them all with Windsor
_windsor.Register(
    clientContractRegistrations.ToArray()
    );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...