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"
Related
I have been getting this error when trying to create or update a user.
The full error is:
The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.
We use autofac in our application, so I after reading this article I created my own IdentityFactoryOptions like this:
public class IdentityFactoryOptions: IdentityFactoryOptions<UserProvider>
{
public IdentityFactoryOptions()
{
DataProtectionProvider = new DpapiDataProtectionProvider("ASP.NET Identity");
}
}
and then I created my own DataProtectionTokenProvider like this:
public class DataProtectionTokenProvider : DataProtectorTokenProvider<User>
{
public DataProtectionTokenProvider(IdentityFactoryOptions options) : base(options.DataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = TimeSpan.FromHours(6);
}
}
I registered both these as SingleInstances like this:
builder.RegisterType<IdentityFactoryOptions>().AsSelf().SingleInstance();
builder.RegisterType<DataProtectionTokenProvider>().AsSelf().SingleInstance();
and I injected the DataProtectionTokenProvider into my UserManager and assigned it in the managers constructor like this:
UserTokenProvider = dataProtectionTokenProvider;
But after doing all this, I still get the error.
I also read this article and saw you have to update your web.config too, so I added this:
<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>
But the error persists.
Does anyone have any solution for this? It is driving me mad....
Ok, I managed to fix this.
Using the first post I linked, I injected the IAppBuilder into my autofac module and removed my IdentityFactoryOptions class. So the registration now looks like this:
builder.Register(m => new DataProtectorTokenProvider(_app.GetDataProtectionProvider())).AsSelf().SingleInstance();
And the DataProtectorTokenProvider looks like this:
public class DataProtectorTokenProvider : DataProtectorTokenProvider<User>
{
public DataProtectorTokenProvider(IDataProtectionProvider dataProtectionProvider) : base(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = TimeSpan.FromHours(6);
}
}
Everything else I kept the same. This solved the issue.
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
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'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" />