Receiving values from WCF Server [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I've setup a WCF Server and Client and all works nicely, i can call the method at the server and receive the object initialised from that call...great.
The problem i have is the Server receives some arguments when it's started, what i can't see is how i can obtain these values from the server as it appears i can't obtain a message or pre-initialised class from the server itself.
Is there a way to provide this information other than saving it to file when the server first receives it then reading that file from the server method?
Thanks

The easiest way is to have a singleton service object. This can be done by marking the service class with ServiceBehavior attribute and passing this object to ServiceHost constructor:
[ServiceContract]
public interface IExampleService
{
[OperationContract]
int GetInitValue();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ExampleService : IExampleService
{
private readonly int initValue;
public ExampleService(int initValue)
{
this.initValue = initValue;
}
public int GetInitValue() => initValue;
}
// ...
// public ServiceHost(object singletonInstance, params Uri[] baseAddresses)
var host = new ServiceHost(new ExampleService(someValue)));
host.AddServiceEndpoint(typeof(IExampleService),
new WSHttpBinding(), "http://localhost:8080");
host.Open();
When singleton mode is not appropriate, one can use dependency injection, e.g. with Unity:
var container = new UnityContainer();
container
.RegisterType<IExampleService, ExampleService>()
// When service object is created, someValue is passed to it's constructor
new InjectionConstructor(someValue));
var host = new ServiceHost(typeof(ExampleService));
host.AddServiceEndpoint(typeof(IExampleService),
new WSHttpBinding(), "http://localhost:8080")
.EndpointBehaviors.Add(new UnityEndpointBehavior(container));
host.Open();
// ...
class UnityEndpointBehavior : IEndpointBehavior
{
private readonly IUnityContainer container;
public UnityEndpointBehavior(IUnityContainer container)
{
this.container = container;
}
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.InstanceProvider =
new UnityInstanceProvider(container, endpoint.Contract.ContractType);
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
class UnityInstanceProvider : IInstanceProvider
{
private readonly IUnityContainer container;
private readonly Type contractType;
public UnityInstanceProvider(IUnityContainer container, Type contractType)
{
this.container = container;
this.contractType = contractType;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return container.Resolve(contractType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
container.Teardown(instance);
}
}

Related

Passing Parameters to WCF constructor

I have a WCF service in c#, that I would like to pass in some parameters upon initialization. Now the error I get is service must be parameter less.
I have read some articles online regarding dependency injection etc. But i'm not sure if that's what i want and have tried a few things and can't seem to get it to work.
I'm also calling it from x++ ax 2012. using ref=AifUtil::createServiceClient(clientType);
to create my service reference, but would like to pass in some parameters upon initial construction of the object. Any simple ideas how to do this ?
You can't use parameterised constructors directly because of WCF default behaviours. However it is possible to do that with using implementaton of ServiceHostFactory, ServiceHost and IInstanceProvider.
Look at this: How do I pass values to the constructor on my wcf service?
EDIT: Added example codes from the link:
Given a service with this constructor signature:
public MyService(IDependency dep)
Here's an example that can spin up MyService:
public class MyServiceHostFactory : ServiceHostFactory
{
private readonly IDependency dep;
public MyServiceHostFactory()
{
this.dep = new MyClass();
}
protected override ServiceHost CreateServiceHost(Type serviceType,
Uri[] baseAddresses)
{
return new MyServiceHost(this.dep, serviceType, baseAddresses);
}
}
public class MyServiceHost : ServiceHost
{
public MyServiceHost(IDependency dep, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (dep == null)
{
throw new ArgumentNullException("dep");
}
foreach (var cd in this.ImplementedContracts.Values)
{
cd.Behaviors.Add(new MyInstanceProvider(dep));
}
}
}
public class MyInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly IDependency dep;
public MyInstanceProvider(IDependency dep)
{
if (dep == null)
{
throw new ArgumentNullException("dep");
}
this.dep = dep;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
return new MyService(this.dep);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
var disposable = instance as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
#endregion
#region IContractBehavior Members
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.InstanceProvider = this;
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
#endregion
}
Register MyServiceHostFactory in your MyService.svc file, or use MyServiceHost directly in code for self-hosting scenarios.
For self-hosted WCF services such as the console, we can initialize the passed parameters directly in the service host life cycle event, or perform specific actions before the service starts.
For the WCF service is hosted in WCF, this feature could be completed by the service host factory property.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/extending-hosting-using-servicehostfactory
https://blogs.msdn.microsoft.com/carlosfigueira/2011/06/13/wcf-extensibility-servicehostfactory/
Here is a detailed example related to authenticating the client with Asp.net membership provider, before the service running, we seed some data in the database.
Svc markup.
<%# ServiceHost Language="C#" Debug="true" Factory="WcfService2.CalculatorServiceHostFactory" Service="WcfService2.Service1" CodeBehind="Service1.svc.cs" %>
Factory.
public class CalculatorServiceHostFactory : ServiceHostFactoryBase
{
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
return new CalculatorServiceHost(baseAddresses);
}
}
class CalculatorServiceHost : ServiceHost
{
#region CalculatorServiceHost Constructor
/// <summary>
/// Constructs a CalculatorServiceHost. Calls into SetupUsersAndroles to
/// set up the user and roles that the CalculatorService allows
/// </summary>
public CalculatorServiceHost(params Uri[] addresses)
: base(typeof(Service1), addresses)
{
SetupUsersAndRoles();
}
#endregion
/// <summary>
/// Sets up the user and roles that the CalculatorService allows
/// </summary>
internal static void SetupUsersAndRoles()
{
// Create some arrays for membership and role data
string[] users = { "Alice", "Bob", "Charlie" };
string[] emails = { "alice#example.org", "bob#example.org", "charlie#example.org" };
string[] passwords = { "ecilA-123", "treboR-456", "eilrahC-789" };
string[] roles = { "Super Users", "Registered Users", "Users" };
// Clear out existing user information and add fresh user information
for (int i = 0; i < emails.Length; i++)
{
if (Membership.GetUserNameByEmail(emails[i]) != null)
Membership.DeleteUser(users[i], true);
Membership.CreateUser(users[i], passwords[i], emails[i]);
}
// Clear out existing role information and add fresh role information
// This puts Alice, Bob and Charlie in the Users Role, Alice and Bob
// in the Registered Users Role and just Alice in the Super Users Role.
for (int i = 0; i < roles.Length; i++)
{
if (Roles.RoleExists(roles[i]))
{
foreach (string u in Roles.GetUsersInRole(roles[i]))
Roles.RemoveUserFromRole(u, roles[i]);
Roles.DeleteRole(roles[i]);
}
Roles.CreateRole(roles[i]);
string[] userstoadd = new string[i + 1];
for (int j = 0; j < userstoadd.Length; j++)
userstoadd[j] = users[j];
Roles.AddUsersToRole(userstoadd, roles[i]);
}
}
}
Official sample.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-membership-provider
Feel free to let me know if there is anything I can help with.

Hadler Error EndPoint in my host - WCF - Behaviour

A few days ago I opened a question if I succeed with the answers. I had not focused the question well, and now with something more knowledge I ask again.
I need to capture the errors of all my endpoints to have them included in the same site. The idea is to add a behavior to these endpoints.
namespace SIPE.Search.Helpers
{
/// <summary>
/// Implements methods that can be used to extend run-time behavior for an endpoint in either a client application.
/// </summary>
public class ExternalClientBehavior : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new ExternalClientBehaviorClass();
}
public override Type BehaviorType
{
get
{
return typeof(ExternalClientBehaviorClass);
}
}
/// <summary>
/// JSON REST[GET] Converter Behavior
/// </summary>
private class ExternalClientBehaviorClass : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
ExternalClientMessageInspector clientInspector = new ExternalClientMessageInspector(endpoint);
clientRuntime.MessageInspectors.Add(clientInspector);
foreach (ClientOperation op in clientRuntime.Operations)
{
op.ParameterInspectors.Add(clientInspector);
}
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
//("Behavior not supported on the consumer side!");
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
}
}
Now I know that it will never enter my ApplyDispatchBehaviour if the client does not implement my behaviour, and this will NEVER happen, since they are external providers and I do not have access to the code.
Also, my first error does not even leave my code, since I'm causing a NOT FOUND error.
I have found many similar sources with my problem without solution. I have found by several sites to add the following in ApplyClientBehaviour:
IErrorHandler errorHandler = new CustomErrorHandler();
clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(errorHandler);
But this does not work.
Other sources that happened to me: https://riptutorial.com/csharp/example/5460/implementing-ierrorhandler-for-wcf-services
It is NOT a solution, since it is for Services Behavior. I need to do it in EndPoint Behavior.
Thank you
Please refer to the following example.
Server side.
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://localhost:1100");
BasicHttpBinding binding = new BasicHttpBinding();
using (ServiceHost sh = new ServiceHost(typeof(MyService), uri))
{
ServiceEndpoint se = sh.AddServiceEndpoint(typeof(IService), binding, "");
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:1100/mex");
sh.Description.Behaviors.Add(smb);
}
MyEndpointBehavior bhv = new MyEndpointBehavior();
se.EndpointBehaviors.Add(bhv);
sh.Open();
Console.WriteLine("service is ready");
Console.ReadKey();
sh.Close();
}
}
}
[ServiceContract(ConfigurationName = "isv")]
public interface IService
{
[OperationContract]
string Delete(int value);
[OperationContract]
void UpdateAll();
}
[ServiceBehavior(ConfigurationName = "sv")]
public class MyService : IService
{
public string Delete(int value)
{
if (value <= 0)
{
throw new ArgumentException("Parameter should be greater than 0");
}
return "Hello";
}
public void UpdateAll()
{
throw new InvalidOperationException("Operation exception");
}
}
public class MyCustomErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
FaultException faultException = new FaultException(error.Message);
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, error.Message);
}
}
public class MyEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
return;
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
return;
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
MyCustomErrorHandler myCustomErrorHandler = new MyCustomErrorHandler();
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(myCustomErrorHandler);
}
public void Validate(ServiceEndpoint endpoint)
{
return;
}
}
Client.
static void Main(string[] args)
{
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
try
{
client.Delete(-3);
}
catch (FaultException fault)
{
Console.WriteLine(fault.Reason.GetMatchingTranslation().Text);
}
}
Result.
Feel free to let me know if there is anything I can help with.

How to pass username and password to the SOAP header of a Web Service Call from C#?

I want to write a C# code which calls a (remote) web service in another machine. For this I have to pass username and password in the SOAP header of the call.
I would like to know an example of code to make this in C#.
the produced XML should be like :
<env:Header>
<ns1:Security>
<ns1:UsernameToken>
<ns1:Username>XXXXXXXXXXXXXXXX</ns1:Username>
<ns1:Password>YYYYYYYYYYYYYYYY</ns1:Password>
</ns1:UsernameToken>
</ns1:Security>
</env:Header>
Thanks in advance
J.
Are many ways to do that. The CustomBinding is more flexible because it allow more controll, for that i propose you with that. Pasing header to endpoint is a simple way:
// binding
var binding = new CustomBinding();
binding.Elements.Clear();
binding.Elements.Add(new TextMessageEncodingBindingElement{MessageVersion = MessageVersion.Soap12});
binding.Elements.Add(new HttpTransportBindingElement{MaxReceivedMessageSize = 20000000,});
// endpoint
var endpoint = new EndpointAddress(new Uri(listeningUri), new MySecurityHeader())
var client = new Client(binding, endpoint);
client.SomeMethod();
where MySecurityHeader is an AddressHeader, for example:
public class MySecurityHeader : AddressHeader
{
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "<provide the appropiate namespace>"; }
}
protected override void OnWriteAddressHeaderContents(System.Xml.XmlDictionaryWriter writer)
{
// here you do what you want
writer.WriteRaw(String.Format(#"
<UsernameToken xmlns=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"">
<Username>user</Username>
<Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"">pass</Password>
</UsernameToken>").Trim());
}
}
this is an example using an IEndpointAdress
var customBinding = new CustomBinding();
customBinding.Elements.Add(new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.Soap12, });
customBinding.Elements.Add(new HttpTransportBindingElement { MaxReceivedMessageSize = 20000000, });
var endpointAddres = new EndpointAddress(listeningUri);
var client = new Client(customBinding, endpointAddres);
// add my own IEndpointBehavior
client.ChannelFactory.Endpoint.Behaviors.Add(new CustomBehavior());
client.SomeMethod();
and this is the CustomBehavior definition
public class CustomBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
var inspector = new CustomMessageInspector();
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{}
public void Validate(ServiceEndpoint endpoint)
{}
}
public class CustomMessageInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
request.Headers.Add(new MyMessageHeader());
return null;
}
}
public class MyMessageHeader : MessageHeader
{
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteRaw(String.Format(#"
<UsernameToken xmlns=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"">
<Username>user</Username>
<Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"">pass</Password>
</UsernameToken>").Trim());
}
public override string Name
{
get { return "MyHeaderName"; }
}
public override string Namespace
{
get { return "MyHeaderNamespace"; }
}
}
Note you have control before send the request and after receive your reply.
I hope this resolve your issue, if you have some problems with this yust ask me.

Action Filters in WCF Services

Is there something Like ActionFilterAttribute (From ASP.NET MVC) in WCF Services (Or anything like that). basically what I want to do is to log what is coming and goint to and from my services, and I don't want to write the logging code in every single ServiceContracts. yes the question is very general but you understand the idea what I want to do.
Yes there is it called as MessageInspectors/ParameterInspectors , here you can read about them
http://msdn.microsoft.com/en-us/library/aa717047%28v=vs.110%29.aspx
This is exactly what you are looking for , WCF custom behavior log logging
http://www.codeproject.com/Articles/243352/LoggingBehavior-How-to-Connect-Log-prints-with-the
Only confusing thing is you can have message inspector on WCF service and WCF proxy as well , in your case you need only for service side
I had to read a lot to find this out, I'm not an expert in WCF but given this information is a little scarce I'm sharing what have worked for me.
My Solution consists of using an OperationBehavior and a DispatcherMessageInspector
OperationBehavior
Allows you to change the binding information, validate de operation
description, and apply dispatcher behaviors.
DispatcherMessageInspector
Allows you to inspect and change the messages that are sent for your
service.
Dispatcher
Gets the messages from the communication channels and sends to the
right operation, and get the result back to the caller.
Service Operation
are your service methods
CODE SOLUTION
MESSAGE INSPECTOR
public class MyMessageInspector : IDispatchMessageInspector
{
List<string> targetOperations = new List<string>();
public MyMessageInspector(OperationDescription operation)
{
this.AddOperation(operation);
}
public void AddOperation(OperationDescription operation)
{
this.targetOperations.Add(operation.Messages[0].Action);
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
if (TargetOperationMatchesRequest(request))
{
request = ChangeMessage(request);
return true;
}else
{
return false;
}
}
public bool TargetOperationMatchesRequest(Message request)
{
string requestAction = request.Headers.To.AbsolutePath;
requestAction = requestAction.Substring(requestAction.LastIndexOf("/"));
string targetOperation = "";
foreach (string targetOperationPath in targetOperations)
{
targetOperation = targetOperationPath.Substring(targetOperationPath.LastIndexOf("/"));
if (targetOperation.Equals(requestAction))
{
return true;
}
}
return false;
}
public Message ChangeMessage(Message oldMessage)
{
Message newMessage = request.CreateBufferedCopy(Int32.MaxValue).CreateMessage();
//Change your message
return newMessage;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
}
OPERATION
public class MyOperation : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
MyMessageInspector inspector = dispatchOperation.Parent.MessageInspectors
.Where(x => x is MyMessageInspector)
.FirstOrDefault() as MyMessageInspector;
if (inspector != null)
{
inspector.AddOperation(operationDescription);
}
else
{
inspector = new MessageInspectors(operationDescription);
dispatchOperation.Parent.MessageInspectors.Add(inspector);
}
}
public void Validate(OperationDescription operationDescription)
{
}
}
CONTRACT
[ServiceContract]
public interface IService
{
[OperationContract]
[MyOperation]
OutputData MyMethod(InputData inputData);
}
SERVICE
public class Service : IService
{
[WebInvoke(Method = "POST", UriTemplate = "/json/MyMethod", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public OutputData MyMethod(InputData inputData)
{
//Implementation
return new OutputData();
}
}

Error activating IAuditRepository No matching bindings are available, and the type is not self-bindable

WCF services. My 1st attempt at IoC with WCF. Calling service from Console app to test. Funny thing is I thought these services were working so I was using them to provide data to test a POC I was working on...little did I know I'd first end up fixing the services!
(Debugging using Cassini)
Versions I'm using:
FluentNHibernate 1.1.0.685
NHibernate 2.1.2.4000
Ninject 2.2.0.0
Ninject.Extensions.Wcf 2.2.0.0
.NET Framework 3.5
This is one of the examples I used as a reference: Pieter De Rycke's Blog
Almost every post I found on SO deals with MVC...I assume my issue is slightly different since this is WCF not MVC.
The Exception:
Error activating IAuditRepository
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IAuditRepository into parameter auditRepository of constructor of type ShotService
1) Request for ShotService
Suggestions:
1) Ensure that you have defined a binding for IAuditRepository.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
Console app failing code: (fails on last line)
ShotServiceClient shotSvc = new ShotServiceClient();
LookupShotAdministeredRequest request = new LookupShotAdministeredRequest();
request.ClientId = "128";
request.ClinicId = "289";
request.RequestingUserId = "1";
List<ShotsAdministeredContract> shots = shotSvc.LookupShotAdministered(request).ShotsAdministered;
The Code:
Global.asax.cs
public class Global : NinjectWcfApplication
{
protected override IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new NHibernateModule(),
new ServiceModule(),
new RepositoryModule()
};
return new StandardKernel(modules);
}
}
NHibernateSessionFactoryProvider.cs
public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NhibernateSessionFactory();
return sessionFactory.GetSessionFactory();
}
}
NHibernateSessionFactory.cs
public class NhibernateSessionFactory
{
public ISessionFactory GetSessionFactory()
{
ISessionFactory fluentConfiguration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(ConfigurationManager.ConnectionStrings["DefaultConnectionString"].ConnectionString)
.Cache(c => c
.UseQueryCache()
.ProviderClass<HashtableCacheProvider>())
.ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<AppointmentMap>()
.Conventions.AddFromAssemblyOf<PrimaryKeyConvention>())
.BuildSessionFactory();
return fluentConfiguration;
}
}
NHibernateModule.cs
public class NHibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
RepositoryModule.cs
public class RepositoryModule : NinjectModule
{
public override void Load()
{
Bind<IAuditRepository>().To<AuditRepository>();
.
.
.
Bind<IShotAdministeredRepository>().To<ShotAdministeredRepository>();
}
}
ServiceModule.cs
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IAuditService>().To<AuditService>();
.
.
.
Bind<IShotService>().To<ShotService>();
}
}
NinjectInstanceProvider.cs
public class NinjectInstanceProvider : IInstanceProvider
{
private Type serviceType;
private IKernel kernel;
public NinjectInstanceProvider(IKernel kernel, Type serviceType)
{
this.kernel = kernel;
this.serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext)
{
return this.GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
//Create the instance with your IoC container of choice...here we're using Ninject
return kernel.Get(this.serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
NinjectBehaviorAttribute.cs
public class NinjectBehaviorAttribute : Attribute, IServiceBehavior
{
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
Type serviceType = serviceDescription.ServiceType;
IInstanceProvider instanceProvider = new NinjectInstanceProvider(new StandardKernel(), serviceType);
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in dispatcher.Endpoints)
{
DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
dispatchRuntime.InstanceProvider = instanceProvider;
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
IAuditRepository.cs
public interface IAuditRepository : IRepository<Audit>
{
}
AuditRepository.cs
public class AuditRepository : Repository<Audit>, IAuditRepository
{
public AuditRepository(ISession session) : base(session) { }
}
ShotRepository.cs
public class ShotRepository : Repository<Shot>, IShotRepository
{
public ShotRepository(ISession session) : base(session) { }
}
ShotService.svc.cs
[NinjectBehaviorAttribute]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class ShotService : IShotService
{
#region Members
private IAuditRepository _auditRepository;
private IClientRepository _clientRepository;
private IClinicRepository _clinicRepository;
private IShotRepository _repository;
private IShotAdministeredRepository _administeredRepository;
private IShotCostRepository _costRepository;
private IUserRepository _userRepository;
#endregion
#region Constructors
public ShotService(IAuditRepository auditRepository, IClientRepository clientRepository, IClinicRepository clinicRepository, IShotRepository repository, IShotAdministeredRepository administeredRepository, IShotCostRepository costRepository, IUserRepository userRepository)
{
_auditRepository = auditRepository;
_clientRepository = clientRepository;
_clinicRepository = clinicRepository;
_repository = repository;
_administeredRepository = administeredRepository;
_costRepository = costRepository;
_userRepository = userRepository;
}
#endregion
#region IShotService Members
.
.
.
public ListAdministeredShotsResponse LookupShotAdministered(LookupShotAdministeredRequest request)
{
ListAdministeredShotsResponse response = new ListAdministeredShotsResponse();
try
{
UserService userService = new UserService(_userRepository, _auditRepository);
User requestingUser = userService.Read(Convert.ToInt32(request.RequestingUserId));
if (userService.HasPermission(requestingUser, Permissions.ScheduleAppointments))
{
ShotAdministeredService service = new ShotAdministeredService(_administeredRepository, _auditRepository);
//Guts of method go here...irrelevant to current issue
}
else
{
throw new InvalidPermissionException("Requesting user does not have sufficient permissions to complete the request.");
}
}
catch (Exception ex)
{
response.FailureReason = ex.Message;
}
return response;
}
.
.
.
#endregion
}
I put a break point in CreateKernel(), it has not been hit. I also put a break point in Load() in NHibernateModule.cs, that break point has also not been hit. <-- Correction...Cassini was "not responding" so I guess I wasn't really debugging ALL of my code. I just did an End Task on Cassini and re-ran the debugger on my services...My break point in CreateKernel() was hit as well as my break point in Load(). My main issue still exists, but at least I know this code is being executed.
You are using Ninject.Extensions.Wcf and you do an own integration into Wcf at the same time. There are two kernel instances involved one of which is configured and the other one not. You should decide which integration to use and configure that kernel properly.

Categories