Question about how to register by type (from CSLA discussion) #3
-
|
From this discussion: I have literally several hundreds of business object factories (for .NET 6 and CSLA 6) that will need registered from three separate assemblies. So my example of "four" was just an example to try and keep it simple. Just wondering how you would recommend that I use your tool to register, from within the BSS program.cs, the CSLA object factories (those that implement an interface Would I need to implement an extension method inside each business layer assembly? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
|
Sorry, you were simplifying for me, I get you now! You don't have to implement an extension method in each assembly, but it's a pattern I like myself. It makes each assembly a little more self-contained and suggests that the assembly takes responsibility for its own registrations, which I appreciate. If you ended up with multiple UIs all making use of the same business object library then there would be no duplication of the discovery code. In the simplest form (in my head at least) it probably doesn't matter what the types inherit from. If your naming convention is consistent, and all of the classes ending in Factory in the assembly are to be registered, then the code I would write would be something like: namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddBusinessObjectFactories(this IServiceCollection services)
{
// Perform auto-discovery of all Factories conforming to standard naming conventions
services.DiscoverTypes()
.Where(t => t.Name.EndsWith("Factory"))
.AsThemselves()
.AsScoped()
.Register();
return services;
}
}
}Then in your startup code, you simply need the line: services.AddBusinessObjectFactories();If you have other factories that you don't want registered in the same assembly, and therefore want to check that they implement a particular interface as part of your filtering of the types to register, then you can do one of the following:
My example uses DiscoverTypes() again, because that's what I prefer; this code would be inside of the business object library. If you want to use DiscoverTypesIn() then that's possible too; that would look something like this: services.DiscoverTypesIn(typeof(AlphaInfoFactory).Assembly)
.Where(t => t.Name.EndsWith("Factory"))
.AsThemselves()
.AsScoped()
.Register();You can use any technique you like to retrieve an instance of the right Assembly over which to perform discovery; this is just one example. |
Beta Was this translation helpful? Give feedback.
-
|
I'm glad you got it to work for you. As always, a little extra thought has made me realise that there were other options for you. You could have used WhereNot() to exclude things. Having said that, WhereNot(!typeof(IBusinessObjectFactory).IsAssignableFrom(type)) doesn't read very well because of the double negative. As an aside, you don't need to include the !type.IsAbstract test in your lambda. This is one of the two built in exclusions - both abstract classes and interfaces are excluded from type discovery by default, as if you'd asked for each exclusion using a WhereNot() filter. What you've got works, and that's the important thing 😄 |
Beta Was this translation helpful? Give feedback.
Sorry, you were simplifying for me, I get you now!
You don't have to implement an extension method in each assembly, but it's a pattern I like myself. It makes each assembly a little more self-contained and suggests that the assembly takes responsibility for its own registrations, which I appreciate. If you ended up with multiple UIs all making use of the same business object library then there would be no duplication of the discovery code.
In the simplest form (in my head at least) it probably doesn't matter what the types inherit from. If your naming convention is consistent, and all of the classes ending in Factory in the assembly are to be registered, then the code I would write would…