Step-by-step creation of an IOC wheel catalogue. NET core released, one step at a time to build an IOC wheel, get some. NET magic, near new speed (i)Make an IOC wheel step-by-step (ii), detailed in the generic plant Detailed generic Plant
Now that I say that the IOC container is a luxury factory, an automated assembly plant, let's start with a factory, build a factory, and then upgrade to an IOC container.
First of all, let's write a most simple abstract factory class, or a previous text message for example
Public class smsfactory { publicstatic ISMS Get () { returnnew Xsms (); } }
And then we figured out how to put this xsms to death on the code, UM, add a registration method and send the SMS object in.
Public class smsfactory { static ISMS _sms; Public Static ISMS Get () { return _sms; } Public Static void Reg (ISMS SMS) { = sms; } }
This code separates the business's reliance on xsms, but still registers an ISMS implementation object at program startup such as: Smsfactory.reg (New Xsms ());
We're wondering if this factory is more complex, and it can only be used to make text messages, can it be made into generic?
Public class where T:class { static T _obj; Public Static T Get () { return _obj; } Public Static void Reg (T obj) { = obj; } }
Well, make a good simple generic factory, we have to figure out, this thing in the system to launch a new good object to go in, a little unscientific ah, can let the factory itself new, try it
Public classFactory<t>whereT:class,New() { Public StaticT Get () {return NewS ();//Dizzy, where's the s from? } Public Static voidReg<s> ()whereS:t {//How to save S (inheriting Class)??? It's a headache. } }
Doesn't look like it. Oh, how do we save the information of the inheriting class in this factory, the wise predecessors thought of a method, with a s information object created not on the line, this object inherits a create method with the interface, get when call this object's Create method
Public classFactory<t>whereT:class { Staticicreate creater; Interfaceicreate {T Create (); } classCreater<u>: IcreatewhereU:t,New() { PublicT Create () {return NewU (); } } Public StaticT Get () {//calling the Create method of the Creater object is actually equivalent to calling the creater<u> new U () returncreater. Create (); } Public Static voidReg<s> ()whereS:t,New() { //here, we have saved the information of S to the Creater object.Creater =NewCreater<s>(); } }
Perfect Ah, with a temporary object to save the inheritance class information, so you can register the inheritance class in the factory class went in, back to the small yellow change to change the SMS module problem, we can also use this generic factory to solve the problem of the dependence of the business of the var SMS = Factory<isms> Get () only to register the implementation class in the configuration that is launched
Can we expand, let him support a single case, the answer is yes, as long as the creater transformation
Public classFactory<t>whereT:class { Staticicreate creater; Interfaceicreate {T Create (); } classCreater<u>: IcreatewhereU:t,New() { PublicT Create () {return NewU (); } } classSingletoncreater<u>: IcreatewhereU:t,New() {T instance; ObjectLocker =New Object(); PublicT Create () {//use double check lock if(Instance = =NULL) { Lock(locker) {if(Instance = =NULL) {Interlocked.exchange (refInstanceNewU ()); } } } returninstance; } } Public StaticT Get () {returncreater. Create (); } Public Static voidReg<s> ()whereS:t,New() {creater=NewCreater<s>(); } Public Static voidRegsingleton<s> ()whereS:t,New() {creater=NewSingletoncreater<s>(); } }
Yo, all right, but there's a lock, can you get rid of the lock, yes, we'll use static readonly magic to create an inner class that will only be created when you access the inner class, and it's thread-safe.
Public classFactory<t>whereT:class { Staticicreate creater; Interfaceicreate {T Create (); } classCreater<u>: IcreatewhereU:t,New() { PublicT Create () {return NewU (); } } classSingletoncreater<u>: IcreatewhereU:t,New() { classInstanceclass { Public Static ReadOnlyT Instance =NewU (); } PublicT Create () {returninstanceclass.instance; } } Public StaticT Get () {returncreater. Create (); } Public Static voidReg<s> ()whereS:t,New() {creater=NewCreater<s>(); } Public Static voidRegsingleton<s> ()whereS:t,New() {creater=NewSingletoncreater<s>(); } }
It's dark magic, and then we can change the generic factory, let him support the parameters, in fact, it is very simple, with a dictionary to save the key and creater the corresponding relationship just
Public classFactory<t>whereT:class { Interfaceicreate {T Create (); } classCreater<u>: IcreatewhereU:t,New() { PublicT Create () {return NewU (); } } classSingletoncreater<u>: IcreatewhereU:t,New() { classInstanceclass { Public Static ReadOnlyT Instance =NewU (); } PublicT Create () {returninstanceclass.instance; } } #regionParameter-freeStaticicreate creater; Public StaticT Get () {returncreater. Create (); } Public Static voidReg<s> ()whereS:t,New() {creater=NewCreater<s>(); } Public Static voidRegsingleton<s> ()whereS:t,New() {creater=NewSingletoncreater<s>(); } #endregion #regionwith parameters.Staticidictionary<string, icreate> creaters =Newsystem.collections.concurrent.concurrentdictionary<string, icreate>(); Public StaticT Get (stringkey) {Icreate ct; if(Creaters. TryGetValue (Key, outCT)) returnCt. Create (); Throw NewException ("not registered"); } Public Static voidReg<s> (stringKeywhereS:t,New() {Creaters[key]=NewCreater<s>(); } Public Static voidRegsingleton<s> (stringKeywhereS:t,New() {Creaters[key]=NewSingletoncreater<s>(); } #endregion }
Well, the generic plant and the magic change complete, support the registration of a single case, test, perfect, is not already have the taste of the IOC, the next step we will change the factory, the transformation to be able to read from the configuration and optimize the acquisition of parameters from the performance
I do not want to cause war, but the real generics are. NET Magic, Java is not a good thing, Java can only reflect, near new performance is the. NET true generics give
Code download, written in VS2015 Update3, without the. NET core can be copied directly out of the code
Make an IOC wheel step-by-step (ii), detailed in the generic plant