jskimming / abioc Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
If a mapping from an interface to a concrete class comes before a factory mapping, then an exception will be thrown is the concrete class cannot be instantiated, e.g. it has multiple constructors.
This was discovered when mapping the Amazon S3 client to the interface, like this:
setup
.Register<IAmazonS3, AmazonS3Client>()
.RegisterFactory<AmazonS3Client>(CreateAmazonS3Client);
AmazonS3Client CreateAmazonS3Client()
{
// Factory function implementation.
}
Since AmazonS3Client
has multiple public constructors, the single constructor registration throw an exception when visited, but since it will be overridden, it should not throw an error.
If they the registrations are swapped, then no exception is thrown.
setup
.RegisterFactory<AmazonS3Client>(CreateAmazonS3Client)
.Register<IAmazonS3, AmazonS3Client>();
If an interface is mapped to a concrete class, like this:
setup.Register<IService, Service>();
And later the concrete class registration is specialised to a factory:
setup.RegisterFactory(() => new Service());
This results in duplicate mappings, where the service cannot be resolved using GetService<IService>()
and if GetServices<IService>()
is called, two instances are returned.
This is caused because both the default (single construct) registration, and the factory registration are interpreted as a mapping, and therefore results in two mappings to the same.
Currently only one is allowed.
I've found this with MediatR when producing a notification handler. A field with this name is created
Factor_MediatR_ICancellableAsyncNotificationHandler`1[[Example_Notification, Example, Version=0_0_0_1, Culture=neutral, PublicKeyToken=null]]
It should be something like this:
Factor_MediatR_ICancellableAsyncNotificationHandler__Example_Notification__
Start with restoring this commit 63759c4
Currently reflection is still used when determining the appropriate visitor for a registration.
This could be cached in a concurrent dictionary to map from the registration type to the list of visitor types:
private static readonly ConcurrentDictionary<Type, Type[]> VisitorTypeCache =
new ConcurrentDictionary<Type, Type[]>();
Hi. Is there any documentation on this?
If a registration requires several assemblies then they all currently need to be manually added to ensure the generated code correctly compiles. This can be quite cumbersome.
It would be better if the assemblies were auto discovered based upon the types used during compilation. There may be circumstances where custom assemblies may require adding, therefore them mechanism of adding assemblies should remain, though hopefully that becomes the exception.
Except for where SingleConstructorRegistrationVisitor is checking.
This is how we can pick-up conflicting registrations, like a two factories registered for the same type.
There are two near identical implementations for retrieving injected dependencies, originally constructor dependencies, and lateley property dependecies.
The logic in both implementations encapsulates:
IEnumerable<>
dependencies.I'm not sure a third implementation could arise, (though it's possible), but it's likely a broader set of collections add amplified types will be supported, e.g. arrays, List<>
, IReadOnlyCollection<>
, Func<>
, Lazy<T>
etc. Therefore consolidating this into a single implementation would be beneficial and DRY.
Not sure yet, most likely an internal static helper method.
FASTER might be faster :)
This will allow internal dependencies to be resolved, without forming part of the final map.
The current mechanism of Registration Visitor initialization uses an Initialize function on the IRegistrationVisitor interface. When further initialization was needed the IRegistrationVisitorEx interface was introduced.
What happens when even more initialization is required IRegistrationVisitorExEx
? It's got a bit of a code smell.
Instead of using an Initialize method on the IRegistrationVisitor
interface, Registration Visitors should express their initialization requirements via constructor parameters (this is an IoC project after all). A very limited (TBD) set of potential objects can be specified.
The VisitorFactory should then be updated to reflect upon the discovered visitors, to dynamically generate a Factory function, but rather than generate Func<object>
, functions generate Func<PotentialArg1, PotentialArg2, object>
functions.
The dynamically generated expression tree will then use the appropriate argument on the constructor. See CodeCompilation.CreateContainerFactory for another example.
Func<PotentialArg1, PotentialArg2, object>
factory functionsThe caching of assemblies may cause an issue if registations differ only by the injected factories.
While this is unlikely, caching should be off by default and only enabled if it is known the factories do not change with registrations.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.