How to configure unity container to provide string constructor value? - c#

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>

Related

Resolve instance with unity 5.0.0

How do I resolve an instance of a class with the new Unity 5.0.0 Resolve() method?
In Unity 4.0.1 I resolved an instances like the example given below with SettingsContext. But this no longer works.
I am thinking it is a matter of giving a second argument to Resolve, but I am not sure howto.
var _unity = UnityConfig.GetConfiguredContainer();
var _settings = _unity.Resolve<SettingsContext>();
With UnityConfig class being defined as
public class UnityConfig
{
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
public static void RegisterTypes(IUnityContainer unity)
{
//all the unity.RegisterType calls
}
}
As normal, load the container.
Next load the named section - the default is "unity", but it could be any tag you want in the config file.
Finally, have the section object configure the container.
var c = new UnityContainer();
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(c);
var ss = c.Resolve<IStorageSystem>();
For the app|web.config, be sure to reference the updated type definition (see assembly).
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="FileBox.IStorageSystem, FileBox" mapTo="FileBox.StorageSystem.Local.LocalFileSystem, FileBox" >
<constructor>
<param name="root">
<value value =""/>
</param>
</constructor>
</register>
</container>

Configuring instances in Unity Container configured in App.Config at runtime

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

Unity configuration with inheritance

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.

Unity Not Resolving Injected Properties from Configuration

I've got a simple object into which I'm trying to inject properties. I'm unclear why this doesn't seem to be working. My properties end up being null after I call resolve.
This is my object:
public interface IBasePage
{
[Dependency]
string Title { get; set; }
[Dependency]
string BaseUrl { get; set; }
}
This is what's in my unity config file:
<register type="IWebActionDriver" mapTo="ConcreteWebDriver"/>
<register type="IBasePage" name="LoginPage" mapTo="LoginPage">
<property name="Title" value="Login Page Title"/>
<property name="BaseUrl" value="http://dev1.company.com"/>
</register>
In the startup method for my unit tests, here's what I'm trying to do:
_container = new UnityContainer();
UnityConfigurationSection configSection =
(UnityConfigurationSection) ConfigurationManager.GetSection("unity");
configSection.Configure(_container, "testContainer");
_page = _container.Resolve<LoginPage>();
My concrete class looks like this:
[InjectionConstructor]
public LoginPage(IWebActionDriver driver)
{
_driver = driver;
_driver.Initialize();
this.CurrentPage = _driver;
}
Lo and Behold, the properties for Title and BaseUrl are null. Is it okay to use both an constructor injection and set properties on the object? Am I doing something else odd here?
The LoginPage is registered as a named registration (which makes sense because you can obviously have more than one IBasePage concrete type). So you should be able to achieve the behavior you want by resolving IBasePage by the name:
_page = _container.Resolve<IBasePage>("LoginPage");
You need to include the namespace and assembly names in the config file like:
<namespace name="MyNameSpace" />
<assembly name="MyAssemblyName" />

How do I correctly use Unity to pass a ConnectionString to my repository classes?

I've literally just started using the Unity Application Blocks Dependency Injection library from Microsoft, and I've come unstuck.
This is my IoC class that'll handle the instantiation of my concrete classes to their interface types (so I don't have to keep called Resolve on the IoC container each time I want a repository in my controller):
public class IoC
{
public static void Intialise(UnityConfigurationSection section, string connectionString)
{
_connectionString = connectionString;
_container = new UnityContainer();
section.Configure(_container);
}
private static IUnityContainer _container;
private static string _connectionString;
public static IMovementRepository MovementRepository
{
get { return _container.Resolve<IMovementRepository>(); }
}
}
So, the idea is that from my Controller, I can just do the following:
_repository = IoC.MovementRepository;
I am currently getting the error:
Exception is:
InvalidOperationException - The type
String cannot be constructed. You must
configure the container to supply this
value.
Now, I'm assuming this is because my mapped concrete implementation requires a single string parameter for its constructor. The concrete class is as follows:
public sealed class MovementRepository : Repository, IMovementRepository
{
public MovementRepository(string connectionString) : base(connectionString) { }
}
Which inherits from:
public abstract class Repository
{
public Repository(string connectionString)
{
_connectionString = connectionString;
}
public virtual string ConnectionString
{
get { return _connectionString; }
}
private readonly string _connectionString;
}
Now, am I doing this the correct way? Should I not have a constructor in my concrete implementation of a loosely coupled type? I.e. should I remove the constructor and just make the ConnectionString property a Get/Set so I can do the following:
public static IMovementRepository MovementRepository
{
get
{
return _container.Resolve<IMovementRepository>(
new ParameterOverrides
{
{
"ConnectionString", _connectionString
}
}.OnType<IMovementRepository>() );
}
}
So, I basically wish to know how to get my connection string to my concrete type in the correct way that matches the IoC rules and keeps my Controller and concrete repositories loosely coupled so I can easily change the DataSource at a later date.
EDIT 09:52:
Just to re-iterate what I'm after. I want to know the correct way to pass the ConnectionString or an IRepositoryConfiguration object (prefer that idea, thanks Mc) to a concrete class from Unity. I'm not too fussed on what I pass, just how I pass it whilst maintaining loose coupling.
You can configure the unity container for this:
IUnityContainer container = new UnityContainer()
.RegisterType<IMovementRepository, MovementRepository>(
new InjectionConstructor("connectionstring goes here"));
in XLM that would probably be something like this:
<type type="foo.IMovementRepository,foo" mapTo="foo.MovementRepository,foo">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="connectionString" parameterType="System.String" >
<value value="conectionstring goes here" type="System.String"/>
</param>
</constructor>
</typeConfig>
</type>
or wrap the connectionstring as mcaaltuntas points out.
Probably the most straight forward way to do this is to set up a constructor section for your mapped type in the unity configuration and inside the constructor section have a parameter element for the connection string that passes in a name value for a connection string you have defined in the connectionStrings section of your web configuration.
Inside your constructor code for the Repository class, have some code that uses the name value of the connection string to get the full connection string from the connectionStrings section.
EDIT:
Here's an example for you using Unity 2.0
In your web.config, specify the connection string and a mapping for unity to map an IRepository<T> to a SqlRepository<T>. Based on your other questions, we'll assume that IRepository<T> is in your model project and SqlRepository<T> is in your DAL project.
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<connectionStrings>
<add name="SqlConnection" connectionString="data source=(local)\SQLEXPRESS;Integrated Security= SSPI; Initial Catalog= DatabaseName;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<unity>
<containers>
<container>
<types>
<type type="ModelProject.IRepository`1, ModelProject" mapTo="DALProject.SqlRepository`1, DALProject">
<constructor>
<param name="connectionString">
<value value="SqlConnection" />
</param>
</constructor>
</type>
</types>
</container>
</containers>
</unity>
</configuration>
Now for the IRepository<T> interface in the model project. In this example, I'm also going to be using LINQ to SQL to return objects from the SQL Database
namespace ModelProject
{
/// <summary>
/// Interface implemented by a Repository to return
/// <see cref="IQueryable`T"/> collections of objects
/// </summary>
/// <typeparam name="T">Object type to return</typeparam>
public interface IRepository<T>
{
IQueryable<T> Items { get; }
}
}
And the SQLRepository<T> class in the DAL project
namespace DALProject
{
/// <summary>
/// Generic class for returning an <see cref="IQueryable`T"/>
/// collection of types
/// </summary>
/// <typeparam name="T">object type</typeparam>
public class SqlRepository<T> : IRepository<T> where T : class
{
private Table<T> _table;
public SqlRepository(string connectionString)
{
// use the connectionString argument value to get the
// connection string from the <connectionStrings> section
// in web.config
string connection = ConfigurationManager.ConnectionStrings[connectionString].ConnectionString;
_table = (new DataContext(connection)).GetTable<T>();
}
/// <summary>
/// Gets an <see cref="IQueryable`T"/> collection of objects
/// </summary>
public IQueryable<T> Items
{
get { return _table; }
}
}
}
Let's also use a custom controller factory to allow unity to return controllers for us. This way, unity will inject any dependencies that the controllers have
In global.asax
namespace WebApplicationProject
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
// your routes
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());
}
}
public class UnityControllerFactory : DefaultControllerFactory
{
private IUnityContainer _container;
public UnityControllerFactory()
{
_container = new UnityContainer();
var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (Type t in controllerTypes)
_container.RegisterType(t, t.FullName);
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(_container);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
// see http://stackoverflow.com/questions/1357485/asp-net-mvc2-preview-1-are-there-any-breaking-changes/1601706#1601706
if (controllerType == null) { return null; }
return (IController)_container.Resolve(controllerType);
}
}
}
And Here's a controller example. PageSize might be defined on a base controller or on the controller as a property.
namespace WebApplicationProject.Controllers
{
public class CustomersController : Controller
{
private IRepository<Customer> _customerRepository;
public int PageSize { get; set; }
public CustomersController() { }
public CustomersController(IRepository<Customer> customerRepository)
{
this._customerRepository = customerRepository;
// let's set it to 10 items per page.
this.PageSize = 10;
}
public ViewResult List(string customerType, int page)
{
var customerByType = (customerType == null) ?
customerRepository.Items : customerRepository.Items.Where(x => x.CustomerType == customerType);
int totalCustomers = customerByType.Count();
ViewData["TotalPages"] = (int)Math.Ceiling((double)totalCustomers/ PageSize);
ViewData["CurrentPage"] = page;
ViewData["CustomerType"] = customerType;
// get the right customers from the collection
// based on page number and customer type.
return View(customerByType
.Skip((page - 1) * PageSize)
.Take(PageSize)
.ToList()
);
}
}
}
When the customers list controller action is invoked, unity will correctly instantiate an instance of SqlRepository<Customer> for the controller and inject this into the constructor. the connectionString string used for SqlRepository<T> is set in the unity configuration and is passed into the constructor for a typed SqlRepository<T>.
I didnt use Unity but I have used configuration objects in these situations. For example you can write your code like this
class Configuration:IRepositoryConfiguration,IMailConfiguration
{
private string connectionString;
//IRepository configurations
public string ConnectionString
{
//read connection string from somewhere
get { return connectionString; }
}
//EMail configurations
public string Smtp
{
get { return smpt; }
}
}
interface IRepositoryConfiguration
{
string ConnectionString { get;}
}
public abstract class Repository
{
public Repository(IRepositoryConfiguration configuration)
{
_connectionString = configuration.ConnectionString;
}
public virtual string ConnectionString
{
get { return _connectionString; }
}
private readonly string _connectionString;
}
So you can register IRepositoryConfiguration and Unity will resolve your configuration objects. Also you can add extra parameters in this approach easily.
Update
I think it is ok to have a constructor that accepts IRepositoryConfiguration object in your concrete classes(abstract repository and MovementRepository). Becase they are implementations details and concrete implementations of IMovementRepository.so they need to know connection string.
Setter or Constructor Injection
I prefer constructor injection over setter injection. I think constructor injection leads more discoverable APIs. in Constructor injection as soon as when you want to instantiate object, you see what an object needs to work but in Setter injection you must learn which property to set to use API. For detailed information you can read Constructor ve Setter Injection
I ll add another way :)
You can use Injection parameters that get passed into the constructor when you register a type. This way you can still use constructor injection.
class Repository : IRepository {
readonly string m_ConnectionString;
public Repository(string connectionString) {
ConnectionString = connectionString;
}
}
//When registering
container.RegisterType<IRepository, Repository>(new InjectionConstructor("connectionstring"));

Categories