zcz527 / autofac

Automatically exported from code.google.com/p/autofac
Other
0 stars 0 forks source link

Can RegisterModule() return ContainerBuilder? #474

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Just found myself wanting to write code like:

var container = new ContainerBuilder()
    .RegisterModule<ModuleA>()
    .RegisterModule<ModuleB>()
    .CreateContainer();

Not suitable everywhere, but nice to make this a one-liner in places that it 
makes sense...

Current return type is void.

Original issue reported on code.google.com by nblumha...@nblumhardt.com on 27 Nov 2013 at 10:20

GoogleCodeExporter commented 8 years ago
Would it be right to return ContainerBuilder, or would it be better to have

RegisterModule<T1>
RegisterModule<T1, T2>
...
RegisterModule<T1, T2, T3, T4, T5, T6, T7, T8, T9>

Sort of like the way Func<T> and Action<T> work?

I'm afraid returning ContainerBuilder is going to make people want to do

builder
  .RegisterModule<ModuleA>()
  .RegisterType<Foo>()
  .As<IFoo>()...

just because the syntax allows it, which isn't so great.

We could also have
RegisterModule(params Type[] moduleTypes)

so you could register all your modules in one line easily
builder.RegisterModule(typeof(ModuleA), typeof(ModuleB)...)

It'd still be two lines to build the container, but it'd solve some of the 
register-lots-of-modules-in-one-line issues you're mentioning.

Original comment by travis.illig on 2 Dec 2013 at 11:45

GoogleCodeExporter commented 8 years ago

Original comment by travis.illig on 2 Dec 2013 at 11:46

GoogleCodeExporter commented 8 years ago

Original comment by travis.illig on 3 Dec 2013 at 6:41

GoogleCodeExporter commented 8 years ago
I see what you mean, agree on the caveats :)

There are a few variations on how modules are registered that could make the 
overloads above a bit crazy - it might be possible to define an interface to 
return, that only exposed the module registration methods and Build()?

May be better to leave everything as-is, happy to close this one if you think 
that's a better idea.

Original comment by nblumha...@nblumhardt.com on 8 Dec 2013 at 1:26

GoogleCodeExporter commented 8 years ago
Looking at the RegisterModule overloads, it doesn't look like we expose 
anything beyond:

RegisterModule(IModule module)
RegisterModule<T>()

...and some scanning RegisterAssemblyModules() overloads. However, there's no 
parameterization. It'd be easy enough to add the overloads to register multiple 
modules if you think it'd help.

Changing the return type from void to some other interface might be a little 
more complex and slightly breaking so I might wait until 4.0 or something for 
that. We've already had some downstream stuff break just by adding an optional 
parameter to an existing method so I'd probably wait on that.

Let me know if you would like the multiple registration overloads; if not, 
let's just close this.

Original comment by travis.illig on 9 Dec 2013 at 4:53

GoogleCodeExporter commented 8 years ago
I think returning a specific interface for chaining is the right approach. That 
shouldn’t be a breaking change because no one is currently expecting a return 
type.

That said, I don’t think the interface would have anything other than the 
RegisterModule method for chaining, and writing your own extension method for 
this isn't hard.

public static class ContainerBuilderExtensions
{
    public static ContainerBuilder MyRegisterModule<TModule>(this ContainerBuilder builder, TModule module) where TModule : IModule
    {
        builder.RegisterModule(module);
        return builder;
    }
}

Original comment by alex.meyergleaves on 10 Dec 2013 at 2:16

GoogleCodeExporter commented 8 years ago
If you guys don't think a new interface will break anything, I'm good with 
that. I just didn't want another Issue #462 popping up (addition of an optional 
parameter to a method broke someone).

I'm on it.

Original comment by travis.illig on 10 Dec 2013 at 4:03

GoogleCodeExporter commented 8 years ago
This issue was closed by revision 54a7de7c99d1.

Original comment by travis.illig on 10 Dec 2013 at 6:15

GoogleCodeExporter commented 8 years ago
OK, give that a shot. I added an IModuleRegistrar interface so you should be 
able to do any of the module registration actions in a chained fashion 
including RegisterAssemblyModules.

builder
  .RegisterModule<ModuleA>()
  .RegisterModule(new ModuleB())
  .RegisterAssemblyModules(myasm);
var container = builder.Build();

Original comment by travis.illig on 10 Dec 2013 at 6:17

GoogleCodeExporter commented 8 years ago
Sweet! Looks great, I'll grab the latest ASAP :)

Original comment by nblumha...@nblumhardt.com on 10 Dec 2013 at 9:35

GoogleCodeExporter commented 8 years ago
In my application, I am referencing a third party library which is built using 
older versions of autofac ( < 3.2.0, where RegisterModule methods were inside 
RegistrationExtensions). I upgraded my 'main' application to use 3.2.0. Now, I 
am getting 
"Method not found: 'Void 
Autofac.RegistrationExtensions.RegisterModule(Autofac.ContainerBuilder, 
Autofac.Core.IModule)'.
" 
exception from that library dll. 

What should be doing now?

Original comment by vdbhai....@gmail.com on 18 Dec 2013 at 12:12

GoogleCodeExporter commented 8 years ago
At this point, what that means is you need to back up to the version of Autofac 
the third-party dependency expects and ask them to update their 
reference/recompile. To the best of my knowledge, there's no way other than 
that to fix it, beyond rolling out this new feature.

Original comment by travis.illig on 18 Dec 2013 at 3:51

GoogleCodeExporter commented 8 years ago
So, Should I expect a fix for this sometime in future Or go about recompiling 
the third-party dependency itself?

Thanks!

Original comment by vdbhai....@gmail.com on 19 Dec 2013 at 7:31

GoogleCodeExporter commented 8 years ago
Under the assumption that the third-party dependency is not one of ours (e.g., 
an Autofac.Extras.* assembly), you'd need to contact the owners of the 
third-party dependency to find out when they plan a fix. There is no current 
plan to roll out this feature. Depending on the timeline of the third-party 
project maintainers, you can make the decision to wait for them or recompile.

Original comment by travis.illig on 19 Dec 2013 at 3:32