2015-08-21 2 views
1

У меня возникли проблемы с настройкой использования класса в замке Виндзор 3.3.0.0Как настроить этот класс ClientBase в замке Виндзор

Класс, как это:

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
public partial class DentalRecordServiceClient : ClientBase<IDentalRecordService>, IDentalRecordService 
{ 
    public DentalRecordServiceClient() 
    { 
    } 

    public DentalRecordServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) 
    { 
    } 

    public DentalRecordServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public DentalRecordServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public DentalRecordServiceClient(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) 
    { 
    } 

    public int GetNumberOfVisits(string fullname, string city, DateTime dateOfBirth) 
    { 
     return base.Channel.GetNumberOfVisits(fullname, city, dateOfBirth); 
    } 
} 

У меня есть два связаны интерфейсы для него, как это:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
[ServiceContractAttribute(ConfigurationName = "IDentalRecordService")] 
public interface IDentalRecordService 
{ 
    [OperationContractAttribute(Action = "http://tempuri.org/IDentalRecordService/GetNumberOfVisits", ReplyAction = "http://tempuri.org/IDentalRecordService/GetNumberOfVisitsResponse")] 
    int GetNumberOfVisits(string fullname, string city, DateTime dateOfBirth); 
} 

и это:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
public interface IDentalRecordServiceChannel : IDentalRecordService, IClientChannel 
{ 
} 
конфигурации

My Castle Windsor, как это:

container.Register(
      Component.For<IDentalRecordService>() 
        .ImplementedBy<DentalRecordServiceClient>()); 

В моем коде, я пытаюсь решить эту услугу с помощью этой линии:

var service = container.Resolve<IDentalRecordService>(); 

Но я получаю следующее сообщение об ошибке:

Castle.MicroKernel.ComponentActivator.ComponentActivatorException : ComponentActivator: could not instantiate DentalRecordServiceClient ----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. ----> System.InvalidOperationException : Could not find default endpoint element that references contract 'IDentalRecordService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.

Я думаю, что понимаю, что моя конфигурация Castle Windsor должна указывать параметры, поэтому один из других конструкторов на DentalRecordService Клиент вызывается, но я не уверен, как или какие данные мне нужно его кормить. Я полностью согласен, что фиктивные данные передаются именно так, как работает линия Resolve.

Любая помощь? Заранее спасибо.

Edit:

Хорошо, я обнаружил, что я могу создать экземпляр объекта непосредственно используя следующий код:

var binding = new BasicHttpBinding(); 
var address = new EndpointAddress("http://myaddress"); 
var service = new DentalRecordServiceClient(binding, address); 

Как я могу сделать это через замок Виндзор?

ТИА

+0

Хорошо, я обнаружил, что я могу создать экземпляр одного из конструкторов правильно, используя следующие параметры конструктора: «вар binding = new BasicHttpBinding() 'и' var address = new EndpointAddress ("http: // myendpoint"); Затем выполните «новый DentalRecordServiceClient (привязка, адрес)». Как я могу сделать то же самое в Castle Windsor? – millie

ответ

0

Я нахожу, что клиенты WCF всегда сложно настроить с помощью IOC. В моем случае я обычно регистрирую интерфейс против фабричного метода, который создает клиента.

container.Register(Component.For<IDentalRecordService>().UsingFactoryMethod(c => 
{ 
    var binding = new BasicHttpBinding(); 
    var address = new EndpointAddress("http://myaddress"); 
    var service = new DentalRecordServiceClient(binding, address); 
    return service; 
})); 

Также можно отобразить IDentalRecordService непосредственно DentalRecordServiceClient и использовать зависимости инлайн как отметил Кшиштоф Kozmic, но фабричные методы могут быть легче понять в первую очередь. Не стесняйтесь играть с рядными зависимостями, однако, это довольно легко тоже:

container.Register(
    Component.For<BasicHttpBinding>(), 
    Component.For<EndpointAddress>().DependsOn(Dependency.OnAppSettingsValue("uri", "endpoint")), 
    // you can get the value from anywhere, here it grabs it from the config file 
    Component.For<IDentalRecordService>().ImplementedBy<DentalRecordServiceClient>()); 
1

Это было лет с тех пор я сделал что-нибудь с WCF, но я думаю, что это имеет мало общего с Виндзор. Исключение, которое вы видите (System.InvalidOperationException), выбрасывается конструктором вашего клиента, а не Виндзором.

В самом деле, если вы должны были заменить ваш var service = container.Resolve<IDentalRecordService>(); с var service = new DentalRecordServiceClient(); результат будет таким же.

Вам необходимо убедиться, что ваша конфигурация WCF верна для этого.

Что касается обновленного ответа, вы можете настроить свою службу с помощью встроенных зависимостей as explained in the documentation.

+0

Согласен. Я не думаю, что это Castle как таковой, я думаю, что мне нужно вызвать один из других конструкторов (кроме стандартного), но я не уверен, какие параметры должны проходить (даже фиктивные значения), чтобы разрешить объект ServiceClient строить. Я согласен, что это не замок, поэтому я переубедил этот вопрос. – millie