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:
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.
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;
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.