Autofac RegisterType for UsingConstructor that inherits from the constuctor parameter type - autofac

Is there a way to tell Autofac to resolve a constructor parameter with a RegisteredType that inherits from the class used in the constructor?
I need to use the HttpClientHandler in the constructor for the HttpClient, but I need the HttpClientHandler to access GetCookies as well... If I register the handler As HttpMessageHandler, It creates the HttpClient properly, but then I have to cast HttpMessageHander to HttpClientHandler, which feels like a hack; Is there a better way to do it?
builder.RegisterType<HttpClientHandler>().As<HttpMessageHandler>().SingleInstance();
builder.RegisterType<HttpClient>().UsingConstructor(typeof(HttpMessageHandler)).SingleInstance();

I haven't written a full test but I think you could insert an AsSelf() into your HttpClientHandler registration.
builder.RegisterType<HttpClientHandler>()
.As<HttpMessageHandler>()
.AsSelf()
.SingleInstance();
So when I am resolving, these come back without issue:
var container = builder.Build();
var handler = container.Resolve<HttpClientHandler>();
var client = container.Resolve<HttpClient>();

Related

Autofac: How do I register generic collections?

I have a couple of classes that take IList<IHero> in the constructor. I would like to register the generic collection List<IHero> in Autofac so that whenever Autofac needs to resolve a service that takes IList<IHero, it returns a new instance of List<IHero>. The code below compiles but I get a ton of error messages at run-time.
builder.RegisterType<List<IHero>>().As<IList<IHero>>();
My current workaround is as follows:
var printer = scope.Reseolve<IPrinter>(new TypedParameter(typeof(IList<IHero>), new List<IHero>();
var newEngine = scope.Resolve<IEngine>(new TypedParameter(typeof(IPrinter), printer));
Don't register collections yourself. Autofac handles collections for you.

How to call constructor with interface arguments when mocking a concrete class with Moq

I have the following class, which uses constructor injection:
public class Service : IService
{
public Service(IRepository repository, IProvider provider) { ... }
}
For most methods in this class, I simply create Moq mocks for IRepository and IProvider and construct the Service. However, there is one method in the class that calls several other methods in the same class. For testing this method, instead of testing all those methods together, I want to test that the method calls those methods correctly and processes their return values correctly.
The best way to do this is to mock Service. I've mocked concrete classes with Moq before without issue. I've even mocked concrete classes that require constructor arguments with Moq without issue. However, this is the first time I've needed to pass mocked arguments into the constructor for a mocked object. Naturally, I tried to do it this way:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
However, that does not work. Instead, I get the following error:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service.
Could not find a constructor that would match given arguments:
Castle.Proxies.IRepository
Castle.Proxies.IProvider
This works fine if Service's constructor takes simple arguments like ints and strings, but not if it takes interfaces that I'm mocking. How do you do this?
Why are you mocking the service you are testing? If you are wishing to test the implementation of the Service class (whether that be calls to mocked objects or not), all you need are mocks for the two interfaces, not the test class.
Instead of:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
Shouldn't it be this instead?
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Service(repository.Object, provider.Object);
I realize that it is possible to mock concrete objects in some frameworks, but what is your intended purpose? The idea behind mocking something is to remove the actual implementation so that it does not influence your test. But in your question, you have stated that you wish to know that certain classes are called on properly, and then you wish to validate the results of those actions. That is undoubtedly testing the implementation, and for that reason, I am having a hard time seeing the goals of mocking the concrete object.
I had a very similar problem when my equivalent of Service had an internal constructor, so it was not visible to Moq.
I added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
to my AssemblyInfo.cs file for the implementing project. Not sure if it is relevant, but I wanted to add a suggestion on the off chance that it helps you or someone else.
It must be old version issue, all is ok with latest version. Nick, Please check!
P.s.: I started bounty by misstake (I had wrong signature in my constructor).

Unity Registration: Hooking up an interface to a pre-registered concrete class

I already have a concrete class registered in my unity container and I want to, later on, register an interface that hooks up to that class but uses the existing registration.
I can do this using the following code but it causes a resolve at registration time...
container.RegisterInstance<IMyClass>(container.Resolve<MyClass>());
Is it possible to hook the code up with all resolution done at the point the interface is resolved?
The trick is to use an InjectionFactory:
container.Register<IMyClass>(
new InjectionFactory(c => c.Resolve<MyClass>()));
It sounds like you want to create a factory type. Here, a Func delegate type is used to avoid the creation of a new custom factory type:
container.RegisterInstance<Func<IMyClass>>(() => container.Resolve<MyClass>());
Your other types can then take a dependency on this factory:
private IMyClass myClass;
public MyOtherType(Func<IMyClass> myClassFactory)
{
this.myClass = myClassFactory();
}
IUnityContainer container = new UnityContainer();
var onlyInstance = new MyClass();
container.RegisterInstance<IMyClass>(onlyInstance);
IMyClass resolved = container.Resolve<IMyClass>();
if (object.ReferenceEquals(onlyInstance, resolved))
{
Console.WriteLine("Equal");
}
This prints "Equal". This is the way I would register the instance in the first place.
In a comment above, you imply that you do not control the initial registration. That's the real issue. I would recommend going down one of the following paths (in order of preference, highest to lowest):
Create your own UnityContainer independent of the pre-registered one
Create a child container with CreateChildContainer
Use named (non-default) mappings

How to inject UrlHelper in MVC using Castle Windsor

I have a component that has a dependency on UrlHelper that I need to register using Castle Windsor. UrlHelper in turn has depdendencies on RequestContext (and RouteCollection).
Now my controller has a Url property of type UrlHelper but cannot really access this as far as I can tell.
What is the most efficient way to register my UrlHelper dependency (using fluent configuration)?
Not pretty and not tested but it should work:
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<UrlHelper>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => {
var context = new HttpContextWrapper(HttpContext.Current);
var routeData = RouteTable.Routes.GetRouteData(context);
return new UrlHelper(new RequestContext(context, routeData));
}));
Future releases of Windsor won't need the FactorySupportFacility to use UsingFactoryMethod.
Anyway it seems rather odd to have a dependency to UrlHelper...
I blogged about it (among other things) few days ago here. It works with (upcoming) Windsor 2.5. Until that, Mauricio's suggestion should be your safest bet.
The only way I've found to do this is to declare an IUrlHelper interface, and to implement a wrapper class around UrlHelper that implements it. Then we can either inject an instance of the wrapper class using IOC, or in unit tests inject a mock object. It's a bit of a pain, but it works.

How to carry out custom initialisation with autofac

I'm adding autofac to an existing project and some of the service implementations require their Initialize method to be called and passed configuration information. Currently I'm using the code:
builder.Register(context =>
{
var service =
new SqlTaxRateProvider(context.Resolve<IUserProvider>());
service.Initialize(config);
return service;
}
).As<ITaxService>()
.SingleInstance();
which works but I'm still creating the object myself which is what I'm trying to get away from this and allow autofac to handle it for me. Is it possible to configure a post create operation that would carry out the custom initialisation?
To give you an idea of what I'm after ideally this would be the code:
builder.RegisterType<SqlTaxRateProvider>()
.As<ITaxService>()
.OnCreated(service=> service.Initialize(config))
.SingleInstance();
Update:
I am using Autofac-2.1.10.754-NET35
.OnActivating(e => e.Instance.Initialize(...))
should do the trick.
You might also investigate the Startable module (see the Startable entry in the Autofac wiki).
Mark's suggestion to do initialisation in the constructor is also a good one. In that case use
.WithParameter(new NamedParameter("config", config))
to merge the config parameter in with the other constructor dependencies.