My event handlers are not auto-subscribing. I'm using NServiceBus-CI 3.0.2044. I had the same issue with NServiceBus-CI 3.0.2027.
<MsmqTransportConfig ErrorQueue="dwh.projectmanagement.documents.notifications.error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig ForwardReceivedMessagesTo="dwh.admin.auditor">
<MessageEndpointMappings>
<add Messages="DWH.Login.EmployeeLoggedInToTIPS, DWH.Events" Endpoint="dwh.webeventpublisher" />
<add Messages="DWH.Login.BuyerLoggedIn, DWH.Events" Endpoint="dwh.webeventpublisher" />
<add Messages="DWH.ProjectManagement.Events" Endpoint="dwh.projectmanagement.commandhandlers" />
<add Messages="DWH.ProjectManagement.Documents.DocumentDistributor.Events" Endpoint="dwh.projectmanagement.documents.documentdistributor" />
</MessageEndpointMappings>
</UnicastBusConfig>
class EndpointConfig : IConfigureThisEndpoint, AsA_Server , IWantCustomInitialization
{
public void Init()
{
log4net.Config.XmlConfigurator.Configure();
var kernel = new StandardKernel();
Configure.With()
.NinjectBuilder(kernel)
.CustomJsonSerializer();
.MsmqTransport()
.IsTransactional(true)
.UnicastBus()
.LoadMessageHandlers()
.CreateBus()
.Start();
// Other DI bindings
}
}
DocumentVersionSignedByBuyer is in the DWH.ProjectManagement.Events assembly.
public class SalesConsultantNotification :
IHandleMessages<DocumentVersionSignedByBuyer>
{
public IBus Bus { get; set; }
private readonly ISalesQueries _salesQueries;
public SalesConsultantNotification(ISalesQueries salesQueries)
{
_salesQueries = salesQueries;
}
public void Handle(DocumentVersionSignedByBuyer message)
{
var salesConsultants = _salesQueries.GetSalesConsultants(message.SaleId);
foreach (var salesConsultant in salesConsultants)
{
var cmd = new NotifySalesConsultantBuyerSigned(salesConsultant, message);
Bus.Send(cmd);
}
}
}
Related
I have WCF service class 'MusicServiceManager' with the constructor that takes the parameter of IAppAmbientState. I need to pass parameter value to MusicServiceManager constructor at time initializing Service Host. I don't want singleton implementation for IAppAmbientState.
Service Contract
[ServiceContract]
public interface IAlbumService
{
[OperationContract]
string TestMessage();
[OperationContract]
IEnumerable<AlbumData> GetAlbums();
[OperationContract(Name = "GetAlbumByID")]
AlbumData GetAlbum(Guid ID);
[OperationContract(Name = "GetAlbumByName")]
AlbumData GetAlbum(string name);
}
AppAmbientState
public class AppAmbientState : IAppAmbientState
{
public IContainer ServiceContainer { get; }
public AppAmbientState(
IContainer container // autofac DIC container
)
{
ServiceContainer = container;
}
}
MusicServiceManager
public class MusicServicesManager : IAlbumService
{
private readonly IAppAmbientState _appAmbientState;
public MusicServicesManager(IAppAmbientState appAmbientState)
{
this._appAmbientState= appAmbientState;
}
public AlbumData GetAlbum(Guid ID)
{
throw new NotImplementedException();
}
Service Host Configuration Class
public class ServiceHostConfiguration : IServiceHostConfiguration
{
private readonly ServiceHost hostMusicServiceManager;
public ServiceHostConfiguration()
{
var container = ContainerConfiguration.Configure();
AppAmbientState AppAmbientStateInstance = new AppAmbientState(container);
// need help here... MusicServiceManager(AppAmbientStateInstance)????
// ideally I don't want to define my base address in class
this.hostMusicServiceManager = new ServiceHost(typeof(MusicServicesManager));
}
public void InitializeService()
{
try
{
this.hostMusicServiceManager.Open();
Console.WriteLine("App Web Services Started. Press [Enter] To Exit ");
}
catch(Exception exp)
{
Console.WriteLine("App Web Services Could Not Start:: ", exp);
}
}
public void CloseService()
{
this.hostMusicServiceManager.Close();
}
}
Autofac DI Container
public static class ContainerConfiguration
{
public static IContainer Configure()
{
var builder = new ContainerBuilder();
//Application Configuration
builder.RegisterType<Application>().As<IApplication>();
builder.RegisterType<ServiceHostConfiguration>().As<IServiceHostConfiguration>();
builder.RegisterType<AppAmbientState>().As<IAppAmbientState>();
builder.RegisterType<MusicServicesManager>().As<IAlbumService>();
Here is my Demo:
This is the project directory:
Program.cs:
using Autofac;
using Autofac.Integration.Wcf;
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace AutofacTest
{
class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Logger>().As<ILogger>();
builder.RegisterType<Service>();
using (IContainer container = builder.Build())
{
ServiceHost host = new ServiceHost(typeof(Service));
host.AddDependencyInjectionBehavior<Service>(container);
host.Open();
Console.WriteLine("The host has been opened.");
Console.ReadLine();
host.Close();
}
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
string Test();
}
public interface ILogger
{
}
public class Service : IService
{
private readonly ILogger logger;
public Service(ILogger logger)
{
this.logger = logger;
}
public string Test()
{
return "TEst1";
}
}
public class Logger : ILogger
{
}
}
App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<system.serviceModel>
<services>
<service name="AutofacTest.Service">
<endpoint address="" binding="basicHttpBinding" contract="AutofacTest.IService" name="TestServiceEndPoint" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" name="TestServiceMexEndPoint" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/TestService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Feel free to let me know if the problem persists.
I've implemented a WCF Service Library (.Net 4.5) which works fine.
Then I tried to implement Unity DI using a custom Servcie Host Factory. Debugging application I noticed that CreateServiceHost method in my factory not being called so that my service constructor which uses a dependency as parameter not being called and I get this error:
"System.InvalidOperationException: The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host."
my custom Service Host Factory:
namespace Amir.CodingChallenge.WcfService.Unity
{
public class UnityServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
UnityServiceHost serviceHost = new UnityServiceHost(serviceType,baseAddresses);
// I register types in RegisterComponents method by coding.
serviceHost.Container = UnityConfig.RegisterComponents();
return serviceHost;
}
}
}
my service:
namespace Amir.CodingChallenge.WcfService
{
public class MovieService : IMovieService
{
IShowService showService;
public MovieService(IShowService showService)
{
this.showService = showService;
}
...
}
}
and App.Config:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add service="Amir.CodingChallenge.WcfService.MovieService"
relativeAddress="./MovieService.svc"
factory="Amir.CodingChallenge.WcfService.Unity.UnityServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
<services>
<service name="Amir.CodingChallenge.WcfService.MovieService">
<endpoint address="" binding="wsHttpBinding" contract="Amir.CodingChallenge.WcfService.IMovieService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:49875/Amir.CodingChallenge.WcfService/MovieService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
"Amir.CodingChallenge.WcfService" is my app Assembly name.
Am I doing something wrong in config? Any help would be appreciated.
And the rest of my codes to give further info in below.
UnityConfig class:
namespace Amir.CodingChallenge.WcfService.Unity
{
public static class UnityConfig
{
static UnityContainer container;
public static UnityContainer RegisterComponents()
{
if (container == null)
container = new UnityContainer();
RegisterTypes();
return container;
}
private static void RegisterTypes()
{
container.RegisterType<IShowService, ShowService>(new HierarchicalLifetimeManager());
}
}
}
UnityServiceHost class:
namespace Amir.CodingChallenge.WcfService.Unity
{
public class UnityServiceHost : ServiceHost
{
public UnityContainer Container { set; get; }
public UnityServiceHost()
: base()
{
Container = new UnityContainer();
}
public UnityServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
Container = new UnityContainer();
}
protected override void OnOpening()
{
if (this.Description.Behaviors.Find<UnityServiceBehavior>() == null)
this.Description.Behaviors.Add(new UnityServiceBehavior(Container));
base.OnOpening();
}
}
}
UnityServiceBehavior class:
namespace Amir.CodingChallenge.WcfService.Unity
{
public class UnityServiceBehavior : IServiceBehavior
{
public UnityInstanceProvider InstanceProvider { get; set; }
private ServiceHost serviceHost = null;
public UnityServiceBehavior()
{
InstanceProvider = new UnityInstanceProvider();
}
public UnityServiceBehavior(UnityContainer unity)
{
InstanceProvider = new UnityInstanceProvider();
InstanceProvider.Container = unity;
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
InstanceProvider.ServiceType = serviceDescription.ServiceType;
ed.DispatchRuntime.InstanceProvider = InstanceProvider;
}
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
public void AddBindingParameters(
ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
}
}
UnityInstanceProvider class:
namespace Amir.CodingChallenge.WcfService.Unity
{
public class UnityInstanceProvider : IInstanceProvider
{
public UnityContainer Container { set; get; }
public Type ServiceType { set; get; }
public UnityInstanceProvider()
: this(null)
{
}
public UnityInstanceProvider(Type type)
{
ServiceType = type;
Container = new UnityContainer();
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return Container.Resolve(ServiceType);
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
#endregion
}
}
Make sure that you are linking to the UnityServiceHostFactory in your Service Markup
<%# ServiceHost
Language="C#" Debug="true"
Service="WcfServiceApplication.Implementation.ProductService"
Factory="WcfServiceApplication.DependencyInjection.WCF.UnityServiceHostFactory"
%>
Finding the Markup code was the issue for me. Just right click on the Svc and click "View Markup"
Then you can add in the UnityServiceHostFactory as the Factory value
Link to Source of Answer
Ensure that the build is copying the project dll to the correct location.
In my case, I was copying for 'bin\debug' and the correct would be 'bin\'.
I am using ServiceStack for the first time on a brand-new project that started off as a ASP.NET MVC. I am hosting ServiceStack API at the root, so my web.config looks like this:
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
</system.webServer>
and my App_Start/RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("*");
}
Here's my service:
[Route("/catalogs/{ID}")]
[DataContract]
public class CatalogRequest : IReturn<Catalog>
{
[DataMember]
public int ID { get; set; }
}
[DefaultView("Catalogs")]
public class CatalogService : Service
{
public object Get(CatalogRequest request)
{
return (request.ID == 9999) ? new Catalog() { ID = 9999 } : null;
}
}
I use the following for testing:
public class TestAppHost : AppHostHttpListenerBase
{
public TestAppHost() : base("TestService", typeof(TestAppHost).Assembly) { }
public override void Configure(Funq.Container container)
{
IoC.Configure(container); // IoC is where all Funq configuration is done
}
}
In my VisualStudio unit test I start up the AppHost like this:
[TestClass]
public class TestHelper
{
public const string TEST_HOST_URL = "http://127.0.0.1:8888/";
private static TestAppHost __AppHost;
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
// Start the test app host.
__AppHost = new TestAppHost();
__AppHost.Init();
__AppHost.Start(TEST_HOST_URL);
}
[AssemblyCleanup]
public static void Cleanup()
{
__AppHost.Dispose();
__AppHost = null;
}
}
When I run my test:
[TestMethod]
public void RequestCatalogByID()
{
var client = new JsonServiceClient(TestHelper.TEST_HOST_URL);
var request = new CatalogRequest() { ID = 9999 };
var response = client.Get(request);
Assert.IsNotNull(response);
}
I get a "Not Found" exception even though the URL seems to be correct: http://127.0.0.1:8888/catalogs/9999.
Pointing the browser to http://127.0.0.1:8888/metadata shows the metadata page with no operations.
What am I doing wrong?
Note the assembly you pass in your AppHost Base constructor should be where all your service implementations are (i.e. not your AppHost), so try instead:
public class TestAppHost : AppHostHttpListenerBase
{
public TestAppHost() : base("TestService", typeof(CatalogService).Assembly){}
...
}
I'm trying to integrate Castle Windsor 2.5.0.1 with WCF on IIS (on XP/windows 2008). but I see that only Castle Windsor 3.0.0 works fine with the Caste.Facilities.WCFIntegration. I'm literally pulling my hair out to find out how to do WCF+Castle 2.5.0.1. I googled a lot to find a working example but failed. Please guide me.
You can do this:
web.config wcf config:
<behaviors>
<serviceBehaviors>
<behavior name="defaultBehaviour">
<createWithIoC />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add
name="createWithIoC"
type="Namespace.CreateWithIocBehaviour, Assembly.Namespace" />
</behaviorExtensions>
</extensions>
public class CreateWithIocBehaviour : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new IocServiceProviderBehaviour();
}
public override Type BehaviorType
{
get { return typeof(IocServiceProviderBehaviour); }
}
}
public class IocServiceProviderBehaviour : IServiceBehavior
{
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
var cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider =
new IocServiceProvider(serviceDescription.ServiceType);
}
}
}
}
}
public class IocServiceProvider : IInstanceProvider
{
private readonly Type _serviceType;
public IocServiceProvider(Type serviceType)
{
_serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return IoC.Resolve<object>(_serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
IoC.Release(instance);
}
}
I am using MVVM pattern for Silverlight.
I have these projects:
MVVMDemo.Data (Ria services link set to MVVMDemo.Data.Web)
MVVMDemo.Data.Web (Contains all RIA services) MVVMDemo.Data.ViewModels
MVVMDemo.Data.Models MVVMDemo (contains all views)
MVVMDemo.Data.Common (contains all interfaces)
This is my RIA services class:
namespace MVVMDemo.Data.Web
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
[EnableClientAccess()]
public class UserServices : LinqToEntitiesDomainService<IssueVisionEntities>
{
public IQueryable<User> GetUsersByLimit(int skip , int take)
{
return this.ObjectContext.Users.Skip(skip).Take(take);
}
public IQueryable<User> GetUsers()
{
return this.ObjectContext.Users;
}
public void InsertUser(User user)
{
if ((user.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(user, EntityState.Added);
}
else
{
this.ObjectContext.Users.AddObject(user);
}
}
public void UpdateUser(User currentUser)
{
this.ObjectContext.Users.AttachAsModified(currentUser, this.ChangeSet.GetOriginal(currentUser));
}
public void DeleteUser(User user)
{
if ((user.EntityState == EntityState.Detached))
{
this.ObjectContext.Users.Attach(user);
}
this.ObjectContext.Users.DeleteObject(user);
}
}
}
This is my model which calls RIA services :-
namespace MVVMDemo.Models
{
[Export(typeof(IUserModel))]
public class UserModel : IUserModel
{
private const int PAGESIZE = 10;
private int skip = 0;
private UserServices _context;
private UserServices Context
{
get
{
if (_context == null)
{
_context = new UserServices();
}
return _context;
}
}
public void GetAllUsersAysnc()
{
PerformQuery<User>(Context.GetUsersQuery(), GetAllUsersAsyncComplete);
}
private void PerformQuery<T>(EntityQuery<T> query , EventHandler<EntityResultArgs<T>> eventHandler) where T:Entity
{
this.Context.Load<T>(query, LoadBehavior.RefreshCurrent, r =>
{
if (eventHandler != null)
{
try
{
if (r.HasError)
{
eventHandler(this, new EntityResultArgs<T>(r.Error));
r.MarkErrorAsHandled();
}
else
eventHandler(this, new EntityResultArgs<T>(r.Entities));
}
catch (Exception ex)
{
eventHandler(this, new EntityResultArgs<T>(ex));
}
}
},null);
}
public event EventHandler<EntityResultArgs<Data.Web.User>> GetAllUsersAsyncComplete;
public void GetAllUsersByLimit()
{
PerformQuery<User>(Context.GetUsersByLimitQuery(skip,PAGESIZE), GetAllUsersByLimitAsyncComplete);
}
public event EventHandler<EntityResultArgs<Data.Web.User>> GetAllUsersByLimitAsyncComplete;
}
Whenever i run the method GetAllUsersAysnc i always get this error :-
http://img408.imageshack.us/img408/6150/62968542.jpg
This is my app.config in MVVMDemo.Data.Web
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="DomainServiceModule" preCondition="managedHandler"
type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<connectionStrings>
<add name="IssueVisionEntities" connectionString="metadata=res://*/IssueVisionModel.csdl|res://*/IssueVisionModel.ssdl|res://*/IssueVisionModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=TAPESH\MSSQLSERVER2008;Initial Catalog=IssueVision;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.web>
<httpModules>
<add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>
</system.web>
</configuration>
And this is my web.config of Asp.Net website which is hosting the silverlight application
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
I have no idea what is happening and I am a beginner in RIA services.