// Sort of registration of factory, because the channel setup is merely a factory containing the data provider instances. public void CreateChannel <T1, T2>(IChannelSetup <T1, T2> setup) where T1 : TBase1 where T2 : TBase2 { // Constructing or expanding the channel setup model in such a way while still having type information // is a better strategy. Doing it afterwards requires a lot more effort using reflection. // - Find endpoints and build configuration using them. var t1Endpoint = Source1.GetEndpoint <T1>(); var t1Extractor = Source1.CreateResolver <T1>(); // Because constraint on this, as a whole this can't be moved into Source itself. var t1TypeConfig = new TypeConfiguration <T1, TId>(t1Extractor, Source2.DefaultExtractorValue); var t1EndpointConfig = new EndpointConfiguration <T1, TId>(t1TypeConfig, t1Endpoint); var t2Endpoint = Source2.GetEndpoint <T2>(); var t2Extractor = Source2.CreateResolver <T2>(); var t2TypeConfig = new TypeConfiguration <T2, TId>(t2Extractor, Source2.DefaultExtractorValue); var t2EndpointConfig = new EndpointConfiguration <T2, TId>(t2TypeConfig, t2Endpoint); var channelConfig = new ChannelConfiguration <T1, T2, TId, ItemMatch <T1, T2> >(t1EndpointConfig, t2EndpointConfig, setup.TypeTranslator); var plumber = PlumberFactory.Create(channelConfig, _rules); // Could move towards a construction where factories are registered instead of the actual objects for preventing to many channels linguering // around in memory. However, right now the channels needs to be singletons and run in sequence due to sqlite limitations of having only one // thread writing! var channel = setup.Create(channelConfig, plumber); _channels.Add(channel); }