I'm attempting to set up the client for a duplex WCF service via Unity 2.0. To do so, I want to insert an implementation of my CallbackContract - IUpdateClient - into an InstanceContext, which is then inserted into my service proxy, in this case a subclass of DuplexClientBase<IUpdateService> called UpdateProxy.
The problem I encounter is, when attempting to use the Proxy as stored in my Unity container to subscribe the client to updates from the service, I receive the following exception:
The InstanceContext provided to the
ChannelFactory contains a UserObject
that does not implement the
CallbackContractType
'..Services..ServiceContracts.IUpdateClient'.
I am accessing the proxy like so:
_container.Resolve<IUpdateService>("updateServiceImpl").Subscribe();
Given my Unity config:
<!-- Interface to implementation mappings -->
<register type="RepositoryInterface" mapTo="Repository" name="repositoryImpl">
<constructor>
<param name="proxy" dependencyName="proxyImpl"/>
</constructor>
</register>
<!-- Here's the bit that doesn't seem to be resolving as expected -->
<register type="UpdateClientInterface" mapTo="UpdateClient" name="updateClientImpl">
<lifetime type="singleton"/>
<constructor>
<param name="repository" dependencyName="repositoryImpl"/>
</constructor>
</register>
<register type="System.ServiceModel.InstanceContext, System.ServiceModel,
Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="instanceContext">
<constructor>
<param name="implementation" dependencyName="updateClientImpl"/>
</constructor>
</register>
<!-- This is the type I'm resolving with the above _container.Resolve() statement -->
<register type="UpdateServiceInterface" mapTo="UpdateService" name="updateServiceImpl">
<constructor>
<param name="callbackInstance" dependencyName="instanceContext"/>
</constructor>
</register>
<register type="ProxyInterface" mapTo="Proxy" name="proxyImpl">
<constructor>
<param name="configurationName">
<value value="ServiceEndpointFromAppConfig"/>
</param>
</constructor>
</register>
I would expect that when I resolve the UpdateService class, seen here:
public class UpdateProxy : DuplexClientBase<IUpdateService>, IUpdateService
{
public UpdateProxy(InstanceContext callbackInstance)
: base(callbackInstance) {}
public void Subscribe() {}
[...]
}
That the Unity container instantiates an InstanceContext (registered as "instanceContext" in config) and, when doing that, it must instantiate the type registered as "updateClientImpl" - which does, in fact, implement IUpdateClient - and pass that into the InstanceContext's constructor as its implementation parameter.
Nonetheless, I receive the error as above.
In Summary (aka "the tl;dr version"): When the Unity container resolves an InstanceContext, it doesn't seem to create its implementation correctly. I don't know if this is an error in configuration, or if I'm fundamentally misunderstanding how the Unity container resolves a set of dependent types. Any guidance on this would be helpful.
The issue you're running into is because you registered the InstanceContext with a name. However, the UpdateProxy type isn't registered at all. So what's happening is the container will attempt to resolve InstanceContext using the default, unnamed registration.
However, since there is no default registration, the defaults kick in and it looks like it is choosing a different constructor.
The fix would be to either register UpdateProxy and set that registration to use the named registration for InstanceContext or to remove the name from the registration for InstanceContext.
Related
I implemented custom exception handler which works, except mappings from xml configuration policy. Those mapping works with standard Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler
My implementation
[ConfigurationElementType(typeof(CustomHandlerData))]
public class IdentityFaultContractExceptionHandler : IExceptionHandler
{
public IdentityFaultContractExceptionHandler(NameValueCollection attributes)
{
}
public IdentityFaultContractExceptionHandler(Type faultContractType, NameValueCollection attributes)
{
}
public IdentityFaultContractExceptionHandler(Type faultContractType, string exceptionMessage, NameValueCollection attributes)
{
}
public IdentityFaultContractExceptionHandler(IStringResolver exceptionMessageResolver, Type faultContractType, NameValueCollection attributes)
{
}
public Exception HandleException(Exception exception, Guid handlingInstanceId)
{
return new Exception();
}
and part of the configuration
<add name="All Exceptions" type="System.Exception, mscorlib" postHandlingAction="ThrowNewException">
<exceptionHandlers>
<add type="MyClass.IdentityFaultContractExceptionHandler, MyClass" exceptionMessage="An error occurred in the service." faultContractType="MyClass.UnexpectedServerFault, MyClass" name="Fault Contract Exception Handler" >
<mappings>
<add source="{Message}" name="Message" />
</mappings>
</add>
</exceptionHandlers>
</add>
When I remove mappping node service works, when I add, then I got error : unrecognize element mappings.
If you are using a CustomHandlerData attribute then your configuration needs to use XML Attributes which then get passed in as a NameValueCollection to the custom handler constructor. If you want to have custom XML then you will have to use Full Design-time Integration. If you want to go down that road then you should look at the FaultContractExceptionHandlerData source code since your code would probably be quite similar.
I have multiple WCF services hosted in IIS to which I'm applying the same custom service behavior. I'm looking for a way to pass several parameters to the behavior through configuration, such as in behaviorExtensions or behavior elements.
If it helps, I'm also adding custom message inspector in ApplyDispatchBehavior, so I will need to pass parameters to the inspector:
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
new ValidatingMessageInspector(<custom parameters>));
}
}
}
Would just creating a configuration section in web.config with the parameters be valid? If so you can just read the config there and apply it, or even just use appSettings if the parameters are basic.
For example, if you have few parameters of basic types, maybe a simple approach could be:
<appSettings>
<add key="Shared.CommonParameter" value="A value" />
<add key="Service1.OneParameter" value="False" />
<add key="Service1.AnotherParameter" value="Some Value" />
<add key="Service2.ADifferentParameter" value="42" />
</appSettings>
That way it would be easy to differentiate what setting belongs to which service (notice the service name prefix in the key), and also have some shared parameters if needed.
If you need something more complex in structure you might want to look into defining custom configuration sections for each service, as is shown here: http://msdn.microsoft.com/en-us/library/2tw134k3%28v=vs.140%29.aspx
But that might be overkill, depending on your needs and expected flexibility.
Is it possible to read mule configuration file path (file endpoints), smtp host /user/password (smtp endpoints) from database.We finally want to provide a User Interface , where the user can edit the properties through the screen.The normal properties file approach (key/Value) pairs was used earlier but needs to change to read these properties from the database.Any help on this will be greatly appreciated.
Yes, you can use a custom properties provider.
Its configuration would look like this:
<spring:bean class="org.mule.DatabasePropertiesProvider" id="DatabasePropertiesProvider"/>
<spring:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="properties">
<spring:bean factory-bean="DatabasePropertiesProvider" factory-method="getProperties" />
</spring:property>
</spring:bean>
And the code for DatabasePropertiesProvider is as simple as this:
public class DatabasePropertiesProvider {
public Properties getProperties() throws Exception {
Properties properties = new Properties();
// get properties from the database
return properties;
}
}
I am using Unity Application Block to load my dependancies, a problem I am having is when all my dependancies are loaded it is behaving abnormally.
I have a service that takes a business interface using constructor injection, and that business interface takes a repository interface as constructor injection. The problem I have is when I load user details from the database the field values are always the same (even after I manually change them in the DB). Therefore I think it is because it is using the same instance EntityFramework context instance for each time the service is opened.
The only way I can get Entity Framework to load the correct details is to recycle IIS.
Is there a way I can force Unity to create new object instances for its dependancies and force them to be dispose when the WCF request has completed?
I have tried using the transient lifetime manager but this is not curing the problem.
Code:
public class UserService : IUserService
{
private IUserAdmin _UserBusiness { get; set; }
public UserService()
{
}
[InjectionConstructor]
public UserService(IUserAdmin userBusiness)
: this()
{
this._UserBusiness = userBusiness;
}
}
public class UserAdmin : BusinessBase, IUserAdmin
{
private IRepository<DBUserAccount> _UserRepository { get; set; }
[InjectionConstructor]
public UserAdmin(IRepository<DBUserAccount> userRepository)
{
this._UserRepository = userRepository;
}
}
public class GenericRepository<T> : IDisposable, IRepository<T> where T : class, new()
{
private Entities _Context;
private ObjectSet<T> _ObjectSet;
public GenericRepository()
{
this._Context = new Entities();
this._ObjectSet = this._Context.CreateObjectSet<T>();
}
}
Unity Config:
<register type="Services.Contracts.IUserService, Server.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be"
mapTo="Services.Implementations.UserService, Server.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be">
<lifetime type="transient"/>
</register>
<register type="Server.Business.Users.IUserAdmin, Server.Business, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be"
mapTo="Server.Business.Users.UserAdmin, Server.Business, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be">
<lifetime type="transient"/>
</register>
<register type="Server.DataLogic.IRepository`1[[Server.DataModels.DBUserAccount, Server.DataModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be]], Server.DataLogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be"
mapTo="Server.DataLogic.GenericRepository`1[[Server.DataModels.DBUserAccount, Server.DataModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be]], Server.DataLogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 683f160d975782be">
<lifetime type="transient"/>
</register>
It seems that you haven't implemented a unit of work pattern in your application. The Unity configuration looks correct but seems that your changes aren't being committed. Look at this blog post from the EntityFramework team to see how you would implement one. You should also ensure the your implementation properly disposes of the EntityFramework context when committing the unit of work as discussed in this SO question and answer
I have three SQL Server databases that a single application retrieves data from. I am using NHibernate to retrieve data from the different databases. I have things set up so that each database has its own repository and class mappings in its own assembly. In my castle.config file I have the database connections setup using the Castle NHibernate Facility:
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<facilities>
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.Windsor" />
<facility id="nhibernate" isWeb="false" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
<factory id="databaseone.factory" alias="databaseone">
<settings>
<!--Settings Here -->
</settings>
<assemblies>
<assembly>DAL.DatabaseOne</assembly>
</assemblies>
</factory>
<factory id="databasetwo.factory" alias="databasetwo">
<settings>
<!--Settings Here -->
</settings>
<assemblies>
<assembly>DAL.DatabaseTwo</assembly>
</assemblies>
</factory>
<factory id="databasethree.factory" alias="databasethree">
<settings>
<!--Settings Here -->
</settings>
<assemblies>
<assembly>DAL.DatabaseThree</assembly>
</assemblies>
</factory>
</facility>
</facilities>
</castle>
All of my repositories have a constructor that take an ISessionFactory as the parameter:
public MyRepository<T> : IRepository<T>
{
public MyRepository(ISessionFactory factory)
{
//Do stuff here
}
}
I have an installer class where I would like to define the various repositories:
//In install method of IWindsorInstaller
container.register(Component.For(typeof(IRepository<>)).ImplementedBy(typeof(MyRepository<>));
Using one database things work fine. When I add the second database to the mix, the same ISessionFactory is injected into all of the repositories. My question is what is the best way to handle this? I could manually specify which ISessionFactory should be injected into which Repository<> but I cannot seem to find documentation on this. The best way would be if I could say something like: For all class mappings in assembly DAL.DatabaseOne, always inject the ISessionFactory corresponding to databaseone.factory; and for all class mappings in assembly DAL.DatabaseTwo, always inject the ISessionFactory corresponding to databasetwo.factory.
Thoughts or suggestions?
This is explained in this post by Fabio Maulo toward the end under the heading 'Configuring your DAOs/Repository for multiple DB'.
He maps the factory individually for each domain class but you could also use reflection on each of the domain assemblies in your case to register the appropriate factory.