I have a speciifc configuration problem.
<configuration>
<configSections>
<section name="custom" type="ConfigurationSample.CustomConfigurationSection, ConfigurationSample"/>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<custom>
<customConfigurations>
<configuration id="CAT1">
<name>Tom</name>
<address type="rent">
<area>Misissipi</area>
</address>
<conifugration/>
<configuration id="Mouse1">
<name>Jerry</name>
<address type="own">
<area>Seatle</area>
</address>
<conifugration/>
<customConfigurations>
</custom>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IAnimal" type="MyApp.IAnimal, MyApp" />
<alias alias="CAT" type="MyApp.CAT, MyApp" />
<alias alias="Mouse" type="MyApp.Mouse, MyApp" />
<container>
<!-- should register CAT instance with name CAT1 at runtime and mapto IAnimal !-->
<!-- should register Mouse with name Mouse1 at runtime and mapto IAnimal !-->
</container>
</unity>
</configuration>
This is my app.config. All I am looking for runtime registering instances in unity container while reading the custom config section since CAT class CAT configuration in its constructor.
My classes:
public interface IAnimal
{
public string Name {get;set}
pubic bool IsLiving();
}
public class Mouse
{
MouseConfig config;
public Mouse(IAnimalConfig config)
{
this.config=config;
}
public string Name {get;set}
pubic bool IsLiving(){
//do something with config
}
}
public class Cat
{
CATConfig config;
public CAT(IAnimalConfig config)
{
this.config=config;
}
public string Name {get;set}
pubic bool IsLiving(){
//do something with config
}
}
I hope you understand where i am leading to. I need to provide config objects as parameter to the derived classes. So based on my customconfig i want to register instances in unity container. So i can work with those instances in my application. since i already know their types and name of those instances i can resolve from container.
Please let me know if i have to add anything more. Thanks
Related
I have a simple structure of classes, interfaces as follows:
public interface IMessagingClient (interface supporting service bus queue operation)
public class ServiceBusMessagingClient : IMessagingClient (real implementation)
public class MockMessagingClient : IMessagingClient (mock implementation for our unit test)
public class FailoverMessagingClient : IMessagingClient (this implementation internally uses 2 clients and switches roles b/w 2 as and when disaster in a datacenter occur)
{
private IMessagingClient PrimaryClient { get; set; }
private IMessagingClient SecondaryClient { get; set; }
}
We load unity config from web.config/app.config and use it in our product code and test code.
We want following:
For production scenario, PrimaryClient and SecondaryClient should of type ServiceBusMessagingClient
For Test scenario, PrimaryClient and SecondaryClient should of type MockMessagingClient
Our current unity config looks like:
<container name="azure">
<register type="IMessagingClient" mapTo="FailoverMessagingClient"/>
</container>
Do we have to use some interceptors to achieve this? Or by defining a ctor in FailoverMessagingClient and using ctor injection?
Some suggestions would be great!
You can do this using named registrations.
For example, given the following example set up:
namespace ConsoleApplication8
{
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
public interface IMessagingClient { }
public class ServiceBusMessagingClient : IMessagingClient { }
public class MockMessagingClient : IMessagingClient { }
public class FailoverMessagingClient : IMessagingClient
{
private readonly IMessagingClient primaryClient;
private readonly IMessagingClient secondaryClient;
public FailoverMessagingClient(IMessagingClient primaryClient, IMessagingClient secondaryClient)
{
this.primaryClient = primaryClient;
this.secondaryClient = secondaryClient;
}
}
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer().LoadConfiguration();
var failOverMessagingClient = container.Resolve<IMessagingClient>("Two");
}
}
}
you can hook up the dependencies using the app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IMessagingClient" type="ConsoleApplication8.IMessagingClient, ConsoleApplication8" />
<alias alias="ServiceBusMessagingClient" type="ConsoleApplication8.ServiceBusMessagingClient, ConsoleApplication8" />
<alias alias="MockMessagingClient" type="ConsoleApplication8.MockMessagingClient, ConsoleApplication8" />
<alias alias="FailoverMessagingClient" type="ConsoleApplication8.FailoverMessagingClient, ConsoleApplication8" />
<container>
<register type="IMessagingClient" name="One" mapTo="ServiceBusMessagingClient" />
<register type="IMessagingClient" name="Two" mapTo="FailoverMessagingClient">
<constructor>
<param name="primaryClient">
<dependency type="IMessagingClient" name="One" />
</param>
<param name="secondaryClient">
<dependency type="IMessagingClient" name="One" />
</param>
</constructor>
</register>
</container>
</unity>
</configuration>
Changing the line
<register type="IMessagingClient" name="One" mapTo="ServiceBusMessagingClient" />
to
<register type="IMessagingClient" name="One" mapTo="MockMessagingClient" />
will allow you to swap out your implementation of IMessagingClient as appropriate.
Personally, I would rather do this using the fluid syntax
var container = new UnityContainer();
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>("One");
container.RegisterType<IMessagingClient, FailoverMessagingClient>("Two",
new InjectionConstructor(new ResolvedParameter<IMessagingClient>("One"), new ResolvedParameter<IMessagingClient>("One")));
var failOverMessagingClient = container.Resolve<IMessagingClient>("Two");
When using the unity container, you can override an existing registration by registering it again for a different class.
For example:
If you run this code:
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>();
container.RegisterType<IMessagingClient, MockMessagingClient>();
The first registration is overridden and so IMessagingClient is mapped to MockMessagingClient. Its like the first line never executed.
You can use this fact, and in your unit test (in the arrange phase or in the setup method of your test class), simply register the IMessagingClient to the mock implementation like this (after loading the XML configuration):
container.RegisterType<IMessagingClient, MockMessagingClient>();
By the way, you might not want to use DI containers in unit tests. Take a look at this question.
I've got a working Unity container configured from code. I have to move to xml configuration, but can't make it correctly. I don't know what I am missing - maybe somebody is out there who knows the solution and can help me out!
My solution is about layering my FIX protocol library correctly, to handle different vendor specific messages differently, but to have a good robust backing API for that.
I have two interfaces:
public interface ICriteria
{
bool AreMet(Message message);
}
public interface IConsumer
{
ICriteria Criteria { get; }
void HandleMessage(Message message);
}
There is a default abstract implementation for the consumers:
namespace Fix.MessageHandling
{
public abstract class Consumer : IConsumer
{
private readonly ICriteria criteria;
protected readonly IProcessor Processor;
public ICriteria Criteria
{
get { return this.criteria; }
}
protected Consumer(IProcessor processor, ICriteria criteria)
{
//...
}
}
}
Then I've got some abstract implementations for different FIX message types: each Consumer abstraction has its own Criteria abstraction. (referenced in the constructor as well) e.g.
namespace Fix.MessageHandling.ExecutionReport
{
public abstract class Consumer : MessageHandling.Consumer
{
protected Consumer(IProcessor processor, Criteria criteria)
: base(processor, criteria)
{
// ...
}
}
public abstract class Criteria : ICriteria
{
// ...
}
}
I register the ICriteria instances from code:
container.RegisterType<ICriteria, Vendor.Criteria.Spot>("SpotCriteria");
container.RegisterType<ICriteria, Vendor.Criteria.Swap>("SwapCriteria");
// etc.
After that I register the IConsumer insatnces, which are in this case ExecutionReportConsumer instances, but I am mapping to IConsumer:
container.RegisterType<
IConsumer,
Vendor.Consumer.Spot>("SpotConsumer",
new InjectionConstructor(
container.Resolve<IProcessor>(),
container.Resolve<ICriteria>("SpotCriteria")));
// etc.
When I resolve IConsumer-s, I can get all my registered Consumers from the UnityContainer:
container.ResolveAll<IConsumer>();
This is how I tried to do this with xml after defining all the aliases:
<register type="ICriteria" mapTo="ForwardCriteria" name="ForwardCriteria" />
<register type="IConsumer" mapTo="ForwardConsumer" name="ForwardConsumer">
<constructor>
<param name="processor" dependencyType="IProcessor" />
<param name="criteria" dependencyType="ExecutionReportCriteria" dependencyName="ForwardCriteria" />
</constructor>
</register>
If I use the xml configuration and I call ResolveAll for IConsumers, I've got an exception
Resolution of the dependency failed, type = "Fix.MessageHandling.IConsumer", name = "ForwardConsumer".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type Criteria does not have an accessible constructor.
At the time of the exception, the container was:
Resolving Fix.Vendor.Consumer.Forward,ForwardConsumer (mapped from Fix.MessageHandling.IConsumer, ForwardConsumer)
Resolving parameter "criteria" of constructor Fix.Vendor.Consumer.Forward(Fix.MessageHandling.IProcessor processor, Fix.MessageHandling.ExecutionReport.Criteria criteria)
Resolving Fix.MessageHandling.ExecutionReport.Criteria,ForwardCriteria
OK, actually I figured this out by myself and I'm a newbie and don't know what to do - so I answer my own question :]
If I register the criteria interface and my concrete criteria implementations to the correct abstract base class, then it works like a charm!
<register type="ICriteria" />
<register type="ExecutionReportCriteria" mapTo="ForwardCriteria" name="ForwardCriteria" />
<register type="IConsumer" mapTo="ForwardConsumer" name="ForwardConsumer">
<constructor>
<param name="processor" dependencyType="IProcessor" />
<param name="criteria" dependencyName="ForwardCriteria" />
</constructor>
</register>
That is how I managed to get it going:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<typeAliases>
<typeAlias alias="ICriteria"
type="Fix.MessageHandling.ICriteria, MoveUnityCode-as-configToXML" />
<typeAlias alias="ExecutionReportCriteria"
type="Fix.MessageHandling.ExecutionReport.Criteria, MoveUnityCode-as-configToXML" />
<typeAlias alias="ForwardCriteria"
type="Fix.MessageHandling.ExecutionReport.ForwardCriteria, MoveUnityCode-as-configToXML" />
<typeAlias alias="IConsumer"
type="Fix.MessageHandling.IConsumer, MoveUnityCode-as-configToXML" />
<typeAlias alias="ForwardConsumer"
type="Fix.MessageHandling.ExecutionReport.ForwardConsumer, MoveUnityCode-as-configToXML" />
<typeAlias alias="IProcessor"
type="Fix.MessageHandling.IProcessor, MoveUnityCode-as-configToXML" />
<typeAlias alias="Processor"
type="Fix.MessageHandling.Processor, MoveUnityCode-as-configToXML" />
</typeAliases>
<container>
<register type="ExecutionReportCriteria" mapTo="ForwardCriteria" name="ForwardCriteria" />
<register type="IProcessor" mapTo="Processor" />
<register type="IConsumer" mapTo="ForwardConsumer" name="ForwardConsumer">
<constructor>
<param name="processor" dependencyType="IProcessor" />
<param name="criteria" dependencyType="ExecutionReportCriteria" dependencyName="ForwardCriteria" />
</constructor>
</register>
</container>
</unity>
I have a class:
public class Foo : IFoo
{
}
and two interfaces:
Public interface IFoo : IBar<SomeType>
{
}
public interface IBar<T>
{
DoSomething(T t);
}
We are using XML Config,the code configuration works fine, but the web.config doesn't.
The error is like:
Resolution of the dependency failed, type = "IFoo", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, IBar`1[SomeType], is an interface and cannot be constructed. Are you missing a type mapping?
mlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IFoo"
type="IFoo, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4bf38905880b60b" />
<alias alias="Foo"
type="Foo, Something, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4bf38905880b60b" />
<container name="SomeName">
<register type="IFoo" mapTo="Foo" />
</container>
</unity>
I believe you're probably using the default instance of the UnityContainer since you didn't mention anything about using a named instance of the container.
<container name="SomeName">
<register type="IFoo" mapTo="Foo" />
</container>
You're registering the mapping to "SomeName" instead of the default container.
Remove
name="SomeName"
I want use NServiceBus with GetEventStore to create CQRS/EventSourcing solution.
I have a set of Events each is stamped with Aggregate type name and Aggregate id. My domain publishes events using NServiceBus. All events derive from one base type.
I want create message handler which subscribes to all events published by domain, so it can save events in EventStore.
I tried subscribe to my base Event but it doesn't work.
Is there any way to subscribe to all types of events? I don't also want to change NServiceBus configuration or add new handler in my EventStore worker each time I create new domain Event.
I've managed to solve the problem. I have a base Event class and I publish events that derive from the base Event class. On my subscriber I subscribe to base Event and Handle method is firing every time derived event is published.
Messages project
public class Event : IEvent
{
}
public class Event1 : Event
{
}
public class Event2 : Event
{
}
Publisher project
Publishers EndpointConfig
namespace SemplePublisherNamespace
{
using NServiceBus;
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher
{
}
}
Publishers OnBusStart class
public class OnBusStart : IWantToRunWhenBusStartsAndStops
{
public IBus Bus { get; set; }
void IWantToRunWhenBusStartsAndStops.Start()
{
Bus.Publish(new Event1());
Bus.Publish(new Event2());
}
void IWantToRunWhenBusStartsAndStops.Stop()
{
}
}
Publishers app.config
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<configuration>
<configSections>
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
<section name="AuditConfig" type="NServiceBus.Config.AuditConfig, NServiceBus.Core"/>
</configSections>
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/>
<AuditConfig QueueName="audit" />
</configuration>
Subscriber project
Subscribers EndpointConfig
namespace SampleSubscriber
{
using NServiceBus;
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server
{
}
}
Subscribers app.config
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<configuration>
<configSections>
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="AuditConfig" type="NServiceBus.Config.AuditConfig, NServiceBus.Core" />
</configSections>
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
<UnicastBusConfig>
<MessageEndpointMappings>
<add Assembly="Messages" Endpoint="SemplePublisherNamespace" />
</MessageEndpointMappings>
</UnicastBusConfig>
<AuditConfig QueueName="audit" />
</configuration>
Note that in MessageEndpointMappings secion when adding mapping we set Endpoint name and it's the same as namespace of EndpontConfig class in Publisher project.
Subscriber's Handler class
public class Subscriber : IHandleMessages<Event>
{
public void Handle(Event message)
{
Console.WriteLine("Handle: "+message.GetType().Name);
}
}
Another possible approach would be to have your Event acting as a generic envelope with the actual content inside:
public class GenericEnvelope
{
...
public XmlElement Message { get; set; }
}
This still lets you subscribe once and then pass whatever the content you want but the advantage of such approach is that the envelope could possibly contain some message-oriented attributes that are not part of the message. Another advantage is that passing the content as XmlElement lets you implement your own message-level security/integrity (signing and/or encryption).
This is my dad class
public class Dad
{
public string Name
{
get;set;
}
public Dad(string name)
{
Name = name;
}
}
This is my test method
public void TestDad()
{
UnityContainer DadContainer= new UnityContainer();
Dad newdad = DadContainer.Resolve<Dad>();
newdad.Name = "chris";
Assert.AreEqual(newdad.Name,"chris");
}
This is the error I am getting
"InvalidOperationException - the type String cannot be constructed.
You must configure the container to supply this value"
How do I configure my DadContainer for this assertion to pass?
Thank you
You should provide a parameterless constructor:
public class Dad
{
public string Name { get; set; }
public Dad()
{
}
public Dad(string name)
{
Name = name;
}
}
If you can't provide a parameterless constructor, you need to configure the container to provide it, either by directly registering it with the container:
UnityContainer DadContainer = new UnityContainer();
DadContainer.RegisterType<Dad>(
new InjectionConstructor("chris"));
or through the app/web.config file:
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<containers>
<container>
<register type="System.String, MyProject">
<constructor>
<param name="name" value="chris" />
</constructor>
</register >
</container>
</containers>
</unity>