Modify the factory type that is completed at the end of this chapter and make it support constructors with parameters.
Analysis:
1. In line with the OCP principle, we do not modify the original Factory <T>, but extend it through inheritance.
2. continue to use the Activator provided by. NET Framework to provide support for constructors with parameters.
3. To make a difference from the original Factory <T> method signature, we require that only arrays explicitly declared as object [] in the new interface be used as the constructor parameters.
Reference answer
1. To avoid ambiguity, first modify the referenced namespace
Using System;
Using F = MarvellousWorks. PracticalPattern. FactoryMethod;
Using Microsoft. VisualStudio. TestTools. UnitTesting;
2. define new factory interfaces and specific factory types
Interface ifacloud: F. ifacloud
{
# Region factory method
TTarget Create <TTarget> (object [] parametes );
TTarget Create <TTarget> (string name, object [] parametes );
# Endregion
}
Class Factory: F. Factory, ifacloud
{
Public TTarget Create <TTarget> (object [] parametes)
{
Return (TTarget) Activator. CreateInstance (registry [typeof (TTarget)], parametes );
}
Public TTarget Create <TTarget> (string name, object [] parametes)
{
Return (TTarget) Activator. CreateInstance (registry [typeof (TTarget), name], parametes );
}
}
3. Write unit test verification
[TestMethod]
Public void CreateInstance ()
{
Var factory = new Factory ()
. RegisterType <IFruit, Apple> ()
. RegisterType <IFruit, Orange> ("o ")
. RegisterType <IVehicle, Bicycle> ()
. RegisterType <IVehicle, Bicycle> ("")
. RegisterType <IVehicle, Train> ("B ")
. RegisterType <IVehicle, Car> ("c ")
. RegisterType <IEntry, EntryWithName> ()
. RegisterType <IEntry, EntryWithName> ("n ")
. RegisterType <IEntry, EntryWithNameAndAgeAndTitle> ("nat ");
# The region constructor has no parameter type.
Assert. IsInstanceOfType (factory. Create <IFruit> (), typeof (Apple ));
Assert. IsInstanceOfType (factory. Create <IFruit> ("o"), typeof (Orange ));
Assert. IsInstanceOfType (factory. Create <IVehicle> (), typeof (Bicycle ));
Assert. IsInstanceOfType (factory. Create <IVehicle> ("a"), typeof (Bicycle ));
Assert. IsInstanceOfType (factory. Create <IVehicle> ("B"), typeof (Train ));
Assert. IsInstanceOfType (factory. Create <IVehicle> ("c"), typeof (Car ));
# Endregion
# Region constructor type with Parameters
// Convert to the new extended interface form
Var f = (ifacloud) factory;
// Use extended functions
Var e1 = f. Create <IEntry> (new object [] {"joe "});
Assert. IsInstanceOfType (e1, typeof (EntryWithName ));
Assert. AreEqual <string> ("joe", (EntryWithName) e1). Name );
Var e2 = f. Create <IEntry> ("nat", new object [] {"joe", 20 });
Assert. IsInstanceOfType (e2, typeof (EntryWithNameAndAgeAndTitle ));
Assert. AreEqual <string> ("joe", (EntryWithName) e2). Name );
Assert. AreEqual <int> (20, (EntryWithNameAndAgeAndTitle) e2). Age );
Assert. AreEqual <string> (EntryWithNameAndAgeAndTitle. DefaultTitle, (EntryWithNameAndAgeAndTitle) e2). Title );
# Endregion
}