Here's what I got:
[TestFixture]
public class CompositionRootTests {
[Test]
public void FormsShouldBeBoundToViewsThroughConventionBinding() {
GivenIHaveANewKernel();
WhenBindingFormsToViews();
// Then
kernel.Get<IMainView>().Should().BeOfType<MainForm>();
}
[Test]
public void InterfacesEndingWithTheWordFactoryShouldBeBoundAsFactoriesThroughConvetionBinding() {
GivenIHaveANewKernel();
WhenBindingFactories();
// Then
kernel.Should()
.Resolve<ICustomerManagementPresenterFactory>()
.WithSingleInstance();
}
private void GivenIHaveANewKernel() { kernel = new StandardKernel(); }
private void WhenBindingFactories() {
kernel.Bind(services => services
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(assembly => assembly.FullName.Contains("MyProject")
&& !assembly.FullName.Contains("Test")))
.SelectAllInterfaces()
.EndingWith("Factory")
.BindToFactory());
}
private void WhenBindingFormsToViews() {
kernel.Bind(services => services
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(assembly => assembly.FullName.Contains("MyProject")
&& !aasembly.FullName.Contains("Tests")))
.SelectAllClasses()
.EndingWith("Form")
.BindSelection((type, baseType) => type
.GetInterfaces()
.Where(iface => iface.Name.EndsWith("View"))));
}
private IKernel kernel;
}
I'd like to write a parametirized Then
method where I could pass the type to be resolved, and the type to which it should be bound.
ThenIShouldResolve<IMainView, MainForm>();
But I wonder whether it is really cleaner than what I actually got with my // Then
comment. In fact, the Given...
and the When...
helper methods were comments such as // Given
and // When
. Then, when I bound my presenters to themselves, I encountered a scenario where those depend on the prior bindings because of my design.
public class MainPresenter : Presenter<IMainView>, IMainViewUiHandler {
public MainPresenter(IMainView view, ICustomerManagementPresenterFactory factory)
: base(view) {
view.Handler = this;
customerManagementPresenterFactory = factory;
}
private readonly ICustomerManagementPresenterFactory customerManagementPresenterFactory;
}
Hence the required prior bindings to the factories and the views in order to bind the presenters, which I feel comfortable with. And because of this requirement, I decided to refactor my code to helper methods with names inpired from BDD.
Because of the way it is written using fluent syntax, I feel like my When
methods aren't clean enough, or my code looks sloppy.
Perhaps could I refactor my
When...
methods to reuse the binding and parameterize the convention instead?
private void WhenBindingClassesUsingConvention(string classesEndingWith, string interfacesEndingWith) {
kernel.Bind(services => services
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(assembly => assembly.FullName.Contains("MyProject")
&& !assembly.FullName.Contains("Tests")))
.SelectAllClasses()
.EndingWith(classesEndingWith)
.BindSelection((type, baseType) => type
.GetInterfaces()
.Where(iface => iface.Name.EndsWith(interfacesEndingWith));
}
private void WhenBindingFactoriesUsingConvention(string interfacesEndingWith) {
kernel.Bind(services => services
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(assembly => assembly.FullName.Contains("MyProject")
&& !assembly.FullName.Contains("Tests")))
.SelectAllInterfaces()
.EndingWith(interfacesEndingWith)
.BindToFactory());
}
Is it overkill or something, I wonder? One way or another, I can't really compress this code anymore, I guess. Perhaps is it cleaner to use parameterized When...
methods?