I wish to create a PresenterFactory that would be responsible, obviously, for the creation of presenter instances.
Based on code sample provided in this question:
and @Pacane's answer, I thought I would go this way:
PresenterFactoryTests
[TestClass]
public class PresenterFactoryTests {
[TestClass]
public class Instance : PresenterFactoryTests {
[TestMethod]
public void ReturnsInstantialized() {
// arrange
Type expected = typeof(PresenterFactory);
// act
PresenterFactory actual = PresenterFactory.Instance;
// assert
Assert.IsNotNull(actual);
Assert.IsInstanceOfType(actual, expected);
}
[TestMethod]
public void ReturnsSame() {
// arrange
PresenterFactory expected = PresenterFactory.Instance;
// act
PresenterFactory actual = PresenterFactory.Instance;
// assert
Assert.AreSame(expected, actual);
}
}
[TestClass]
public class Create : PresenterFactoryTests {
[TestMethod]
public void ReturnsAuthenticationPresenter {
// arrange
Type expected = typeof(IAuthenticationPresenter);
// act
IAuthenticationPresenter actual =
PresenterFactory
.Instance
.Create<IAuthenticationPresenter, IAuthenticationView>(
new MembershipService());
// assert
Assert.IsInstanceOfType(actual, expected);
}
// Other tests here...
}
}
PresenterFactory
public sealed PresenterFactory {
private PresenterFactory() { }
public static PresenterFactory Instance { get { return getInstance(); } }
P Create<P, V>(params object[] args) where P : IPresenter<V> where V : IView {
V view = (V)Activator.CreateInstance<V>();
return Activator.CreateInstance(typeof(P), view, args);
}
private static PresenterFactory getInstance() {
if (instance == null) instance = new PresenterFactory();
return instance;
}
private static PersenterFactory instance;
}
ApplicationPresenter
public class ApplicationPresenter : Presenter<IApplicationView>, IApplicationPresenter {
public ApplicationPresenter(IApplicationView view, PresenterFactory presenters)
: base (view) {
Presenters = presenters;
// other initializing stuff here...
}
}
However, because of the type constraints, it seems that I am unable to do so as stated in the test above-mentioned.
In my PresenterFactoryTests.Create.ReturnsAuthenticationPresenter
test method, when I use interfaces as type parameters, it compiles and throws on runtime becuase the Activator.CreateInstance
can't create an instance of an interface.
Aside, if I input the concrete types, it complains that it cannot explicitely convert type to my type constraints, albeit both implements the given interfaces.
The PresenterFactory
is required by the ApplicationPresenter
, I shall inject it through its constructor so that the application may instantiate all the available presenters depending on the feature being asked by the user.
What am I missing?
I think you need one more generic argument - concrete type of view because you need 2 concrete types (view and presenter to be able to create them) and type of view's interface:
P Create<P, V, IV>(params object[] args)
where P : IPresenter<V> where V :IV, IV: IView {