Have to register every class before the autofac container can resolve? - autofac

let's say this scenario:
public class B {};
public class C
{
public C(B b){}
}
To resolve C from Autofac container, I have to register both B and C to container.
But, today I used Unity, it seems I just need to register B to container, then C can be resolved.
So Autofac can't do as Unity do?

With out-of-the-box Autofac it is expected that every type you want to use is registered with the container, either directly using the Register... methods or in bulk using RegisterAssemblyTypes. But there are other options too, take a look at Nicholas article about resolving everything. So yes, Autofac can do what Unity does, but you'll have to enable it.
Update: actually, the "resolve anything" feature is built-in now, and you can do the following:
var cb = new ContainerBuilder();
cb.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
return cb.Build();
With the AnyConcreteTypeNotAlreadyRegisteredSource you can actually resolve both C and B without registering any of them.
Note that the lifetime of services resolved by AnyConcreteTypeNotAlreadyRegisteredSource will be "per dependency scope".
Note: this topic over at the Autofac discussion group is related.

Related

Autofac RegisterAssemblyTypes tries to resolve all public types

Quick question: I've been using autofac with asp.net core in a project and I've noticed that it tries to resolve all types during configuration after updating it to the latest nuget package (going from Autofac.Extensions.DependencyInjection 5.0.1 to 7.0.2). Btw, here's the code that was being used to register the types:
builder.RegisterAssemblyTypes(typeof(Utilizador).Assembly)
.AsImplementedInterfaces()
.AsSelf();
Until now, I wasn't seeing this behavior. The problem with this new approach is that it will try to resolve types that will never be injected through DI. For instance, it complains about public classes that don't have public constructors event though those classes will never be created through DI.
Can someone point me to when this change happened?
Does this mean that now I must filter the types I need explicitly?
Thanks.
This is nothing new.
You can filter those out with something like below:
builder.RegisterAssemblyTypes(ThisAssembly)
.Where(type => type.GetConstructors(BindingFlags.Public).Any())
.AsImplementedInterfaces();

Resolution of ILifetimeService fails in autofac 4.6.2

We're refactoring an older system to use DI. Sadly, some of the "core" components that are used all over everywhere have injection unfriendly constructors (descriptions, for example), so we have to use ServiceLocator to create them. Refactoring them is very impractical at this time.
We're trying to create the unfriendly classes by injecting ILifetimeScope into the appropriate place, but are getting the following exception:
No constructors on type 'Autofac.Core.Registration.ScopeRestrictedRegistry' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'.
If I cheat and use the "Update" method on the ContainerBuilder and then register the container as the LifetimeScope, the resolution works successfully, however, given that Update is obsolete, it's not something I want to do.
Can anyone help?
Edit: I'm not doing anything special. Build up is standard:
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
this.Container = builder.Build();
builder = new ContainerBuilder();
builder.RegisterInstance(this.Container);
builder.RegisterInstance(this.Container).As<ILifetimeScope>();
builder.Update(this.Container);
Without these lines
builder = new ContainerBuilder();
builder.RegisterInstance(this.Container);
builder.RegisterInstance(this.Container).As<ILifetimeScope>();
builder.Update(this.Container);
any class with an ILifetimeScope dependency fails with the error above.
public class MyClass : IMyClass
{
public MyClass(ILifetimeScope scope)
{
...
}
}
I'm actually thinking that this is a bug in the Autofac Framework, so I'm hoping that someone from the team will be able to tell me more.
ILifetimeScope is supposed to automatically be available.

Looking for equivalent Windsor Castle's features in Autofac

I have been been Windsor Castle IoC container for the last 3 years; I am trying to put together a proof of concept using Autofac and is having trouble finding equivalent Windsor's Castle's features in Autofac.
• In Windsor Castle's IWinsorContainer API, there is a Release method that allow immediate release of a component instance. Is there an equivalent method in Autofac container?
• Windsor Castle has a concept of “pooled” lifestyle, please see the link below. Is there an equivalent in Autofac?
http://www.castleproject.org/container/documentation/trunk/manual/coretypedocs/Generated_PooledAttribute.html
• Windsor Castle’s DynamicProxy provide a way to do method interception. I found the link below and followed Nicholas’s instruction but I am not able to find the IInterceptor interface in AutofacContrib.DynamicProxy2 or the source code that he mentioned.
http://nblumhardt.com/archives/aop-with-autofac-and-dynamicproxy2/
I would appreciate any information you could provide!
There is no explicit Release in Autofac. Component lifetimes in Autofac are managed by lifetime scopes. The closest you could probably get to explicit release of an object is to make use of the IDisposable support inherent in lifetime scopes.
Say you have a class that implements IDisposable and you register it:
var builder = new ContainerBuilder();
builder.RegisterType<SomeComponent>().As<IMyDependency>().InstancePerLifetimeScope();
var container = builder.Build();
If you create a lifetime scope from which to resolve the component, then when the lifetime scope is disposed, so is your component:
using(var lifetime = container.BeginLifetimeScope())
{
var myThing = lifetime.Resolve<IMyDependency>();
// myThing.Dispose() gets called at the end of the using
}
Alternatively, you may look into owned instances, where you control when IDisposable.Dispose() gets called.
There is no equivalent of the Pooled lifetime in Autofac. You have your choice of...
Per Dependency: Create a new instance each time the component is resolved.
Per Lifetime Scope: Create a new instance once for each owning lifetime scope (like you saw in the above example).
Single Instance: Just create one.
There's a wiki article about the lifetime scopes available here.
You could probably do some custom coding to get pooling to work involving creation of a custom IComponentLifetime implementation and an extension to IRegistrationBuilder so you could do something like...
builder.RegisterType<Foo>().As<IFoo>().PooledLifetime(32);
...but I don't think it'll be a one-or-two-line thing. If you do end up creating it, consider contributing back to AutofacContrib.
The IInterceptor interface is in Castle.Core.dll - Castle.DynamicProxy.IInterceptor - not in AutofacContrib.DynamicProxy2.

With Autofac what would be the advantages and disadvantages

I've read about Autofac that it's fast. I've seen the coding involved and it's pretty neat. But I'm not quite sure how to use it. I've used StructureMap, and it has a static ObjectFactory. Ninject has the Kernel, but in Autofac's Google pages they recommend doing something like this :
using( var resolver = builder.Build() ){
var whatINeed = resolver.Resolve<INeedThisService>();
}
It's a WinForms app, so I got an Invalid Object state from doing the above, so I switched to having a global IContainer, and did it this way
using( var resolver = Program.Container.CreateInnerContainer() )
{
var whatINeed = resolver.Resolve<INeedThisService>();
}
I've used it about 3 or 5 times. But is that efficient? Or should I just do something like
var whatINeed = Program.Resolve<INeedThisService>()
and under the covers
internal static TServervice Resolver<TService>(){
if(_container == null ) _container = builder.Build();
return _container.Resolve<TService>();
}
Which would you use, and why? Also is there a penalty for working with CreateInnerContainer()?
I am not an AutoFac expert but do have experience with other Ioc containers. I thought this question would give me a reason to try AutoFac.
Designs based on Ioc containers should strive to isolate all code from having access to the container except at the entry point or host level. I created the following example using AutoFac and WinForms to show how a form could access a service via it's constructor.
I'm not quite sure why you thought you needed the inner container. Perhaps you could comment and I can provide a more detailed response.
static class Program
{
[STAThread]
static void Main()
{
var builder = new ContainerBuilder();
builder.Register<TheService>().As<INeedThisService>();
builder.Register(f => new Form1(f.Resolve<INeedThisService>())).As<Form1>();
using (var container = builder.Build())
{
Application.Run(container.Resolve<Form1>());
}
}
}
public interface INeedThisService { }
public class TheService : INeedThisService
{
public TheService() { Console.WriteLine("ctor ThisService"); }
}
public partial class Form1 : Form
{
public Form1(INeedThisService service)
{
Console.WriteLine("ctor Form1");
InitializeComponent();
}
}
1) From the examples you gave I could make an assumption that you are trying to use IOC container primarily as service locator. Although almost all containers support it, main usage would be Dependency Injection. That means you should avoid calling Resolve method at all and let container inject all dependencies for you. The differences between two of them (Service Locator and Dependency Injection) is beyond this topic.
2) If you still want to use it as service locator you can just use root container (Program.Container in your case) without creating inner containers. The sequence would be:
Create ContainerBuilder
Register you components in the builder
Create root container: builder.Build()
Access root container to resolve component instances
3) Container hierarchies can be useful in the scenarios where you need singleton behaviour in different scopes:
Global \ Session \ Request (Web applications)
Application \ Plugin (Desktop plugin-based applications)
BTW Autofac encourage people to use tagged contexts to solve such problems:
As Mark Lindell pointed out, you don't generally need to access the container directly in an Autofac application.
The recommended approach is to access it once, as Mark has done, when the application starts up.
Other components that subsequently need to create objects can declare a constructor parameter of type IContext, which Autofac will automatically inject.
An alternative, that does not require any dependency on the Autofac assembly, is to use Generated Factories as described at: http://code.google.com/p/autofac/wiki/DelegateFactories
Hope this helps!

Windsor Container: How to specify a public property should not be filled by the container?

When Instantiating a class, Windsor by default treats all public properties of the class as optional dependencies and tries to satisfy them. In my case, this creates a rather complicated circular dependency which causes my application to hang.
How can I explicitly tell Castle Windsor that it should not be trying to satisfy a public property? I assume there must be an attribute to that extent. I can't find it however so please let me know the appropriate namespace/assembly.
If there is any way to do this without attributes (such as Xml Configuration or configuration via code) that would be preferable since the specific library where this is happening has to date not needed a dependency on castle.
You can use the Castle.Core.DoNotWireAttribute attribute to stop a property from being wired up by the IoC container (this is in the Castle.Core assembly, which means your library only needs to take a dependency on the lightweight Castle.Core assembly - if for example you want to use the code without an inversion of control container altogether, or in a different IoC container).
I don't believe there's any way to prevent wiring from occurring in the Xml configuration, but it would be reasonably easy to add support for this - if I had to do this I would probably:
Introduce some kind of attribute on the property declaration in the xml: <myprop wire="false" />
Inherit from PropertiesDependenciesModelInspector, overriding the InspectProperties method to apply some additional logic to identifying which properties should be added as dependencies to the components model (inspecting the model.Configuration for the wire="false" attribute/value pair).
Inherit from DefaultComponentModelBuilder and override the InitializeContributors to include your replacement PropertiesDependenciesModelInspector - or just remove the existing properties contributor and add your own at run time via the AddContributor/RemoveContributor methods.
Replace the ComponentModelBuilder service instance assigned to the kernel of your container.
Another approach which could work for you is to just manually remove the dependencies from the model before any instances of the service are requested ie.
kernel.GetHandler(typeof(MyComponent)).ComponentModel.Dependencies.RemoveAll(d => d.DependencyKey == "PropertyThatShouldNotBeWired");
YMMV with that approach though - especially if you have startable services or other facilities which may be eagerly instantiating your component after it's registered.
I created a facility to help with this:
Castle.Facilities.OptionalPropertyInjection
I do not know which version of Castle you guys were using at that time, but none of the solution mentioned were working. Plus, there is a lot of dead links.
With castle 3.1, here the solution I came up with (thanks to some castle source code digging):
container.Register(Component.For(type)
.LifestyleTransient()
.Properties( propertyInfo => propertyInfo.PropertyType != typeof(MyOtherType)));
The 'Properties' function adds a property filter used by castle when constructing the ComponentModel. In my case, all properties dependency will be satisfied except the property type 'MyOtherType'.
Maybe it will be helpful for someone. In Windsor 4.1 there is PropertiesIgnore method during registration.
Component.For<Role>().LifestyleTransient().PropertiesIgnore((model, propertyInfo) => true)
DoNotWireAttribute
Class: http://svn.castleproject.org:8080/svn/castle/trunk/Core/Castle.Core/Attributes/DoNotWireAttribute.cs
Test: http://svn.castleproject.org:8080/svn/castle/trunk/InversionOfControl/Castle.Windsor.Tests/IgnoreWireTestCase.cs
This can be achieved by the following code:
var container = new WindsorContainer();
// We don't want to inject properties, only ctors
var propInjector = container.Kernel.ComponentModelBuilder
.Contributors
.OfType<PropertiesDependenciesModelInspector>()
.Single();
container.Kernel.ComponentModelBuilder.RemoveContributor(propInjector);
Source Castle Windsor Documentation
Posted this on the google groups forum too here: http://groups.google.com/group/castle-project-devel/browse_thread/thread/43aa513817bd057a