WCFサービス。WCFを使用したIoCでの最初の試み。テストするためにコンソールアプリからサービスを呼び出します。面白いことに、これらのサービスは機能していると思ったので、それらを使用して、作業中のPOCをテストするためのデータを提供していました...最初にサービスを修正することになるとはほとんど知りませんでした。
(カッシーニを使用したデバッグ)
私が使用しているバージョン:
- 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
これは私が参照として使用した例の1つです:PieterDeRyckeのブログ
SOで見つけたほとんどすべての投稿はMVCを扱っています...これはMVCではなくWCFであるため、私の問題は少し異なると思います。
例外:
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.
コンソールアプリの失敗コード:( 最後の行で失敗)
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
}
CreateKernel()にブレークポイントを設定しましたが、ヒットしていません。また、NHibernateModule.csのLoad()にブレークポイントを設定しましたが、そのブレークポイントもヒットしていません。 <-訂正...カッシーニは「応答していなかった」ので、コードのすべてを実際にデバッグしていなかったと思います。カッシーニで終了タスクを実行し、サービスでデバッガーを再実行しました... CreateKernel()のブレークポイントとLoad()のブレークポイントがヒットしました。私の主な問題はまだ存在しますが、少なくともこのコードが実行されていることはわかっています。