Simple Injector and SolrNet

c#, simple-injector, solrnet

Solution

That Unity configuration looks overly complex, the Ninject configuration is much simpler. I'm not sure why that Unity configuration is that complex.

I grabbed the Ninject configuration and translated to Simple Injector. Since I'm not familiar with Solr, it could be that Solr depends a few extra tweaks in the Simple Injector configuration, but I think this will get you going:

// using SimpleInjector;

public static void Configure(Container container, string serverURL)
{
    container.RegisterInstance<IReadOnlyMappingManager>(
        new MemoizingMappingManager(new AttributesMappingManager()));
    container.Register<ISolrDocumentPropertyVisitor, DefaultDocumentVisitor>();
    container.Register<ISolrFieldParser, DefaultFieldParser>();
    container.Register(typeof(ISolrDocumentActivator<>), typeof(SolrDocumentActivator<>));
    container.Register(typeof(ISolrDocumentResponseParser<>), typeof(SolrDocumentResponseParser<>));
    container.Register<ISolrFieldSerializer, DefaultFieldSerializer>();
    container.Register<ISolrQuerySerializer, DefaultQuerySerializer>();
    container.Register<ISolrFacetQuerySerializer, DefaultFacetQuerySerializer>();

    container.Collection.Register(typeof(ISolrResponseParser<>), new[] { 
        typeof(ResultsResponseParser<>), 
        typeof(HeaderResponseParser<>), 
        typeof(FacetsResponseParser<>), 
        typeof(HighlightingResponseParser<>), 
        typeof(MoreLikeThisResponseParser<>), 
        typeof(SpellCheckResponseParser<>), 
        typeof(StatsResponseParser<>), 
        typeof(CollapseResponseParser<>) 
    });

    container.Register<ISolrHeaderResponseParser, HeaderResponseParser<string>>();

    container.Collection.Register<IValidationRule>(new[] { 
        typeof(MappedPropertiesIsInSolrSchemaRule), 
        typeof(RequiredFieldsAreMappedRule), 
        typeof(UniqueKeyMatchesMappingRule)
    });

    container.RegisterInstance<ISolrConnection>(new SolrConnection(this.serverURL));
    container.Register(typeof(ISolrQueryResultParser<>), typeof(SolrQueryResultParser<>));
    container.Register(typeof(ISolrQueryExecuter<>), typeof(SolrQueryExecuter<>));
    container.Register(typeof(ISolrDocumentSerializer<>), typeof(SolrDocumentSerializer<>));
    container.Register(typeof(ISolrBasicOperations<>), typeof(SolrBasicServer<>));
    container.Register(typeof(ISolrBasicReadOnlyOperations<>), typeof(SolrBasicServer<>));
    container.Register(typeof(ISolrOperations<>), typeof(SolrServer<>));
    container.Register(typeof(ISolrReadOnlyOperations<>), typeof(SolrServer<>));
    container.Register<ISolrSchemaParser, SolrSchemaParser>();
    container.Register<IMappingValidator, MappingValidator>();
}

Problem

I'm moving from the easy world of Ninject over to the fast world of Simple Injector, but I'm getting stuck with SolrNet. A lot of the popular IoC's have SolrNet integrations already, but not SimpleInjector. I've started creating my own integration by converting the Unity stuff found at https://github.com/mausch/SolrNet/tree/master/Unity.SolrNetIntegration Does anyone either know if this has been done before ( by someone with better knowledge than me) or can anyone convert the below to use simple injector: ``` private static void RegisterSolrOperations(SolrCore core, IUnityContainer container, bool isNamed = true) { var ISolrReadOnlyOperations = typeof (ISolrReadOnlyOperations<>).MakeGenericType(core.DocumentType); var ISolrBasicOperations = typeof (ISolrBasicOperations<>).MakeGenericType(core.DocumentType); var ISolrOperations = typeof (ISolrOperations<>).MakeGenericType(core.DocumentType); var SolrServer = typeof (SolrServer<>).MakeGenericType(core.DocumentType); var registrationId = isNamed ? core.Id : null; var injectionConstructor = new InjectionConstructor( new ResolvedParameter(ISolrBasicOperations, registrationId), new ResolvedParameter(typeof (IReadOnlyMappingManager)), new ResolvedParameter(typeof (IMappingValidator))); container.RegisterType(ISolrOperations, SolrServer, registrationId, injectionConstructor); container.RegisterType(ISolrReadOnlyOperations, SolrServer, registrationId, injectionConstructor); } ``` So far I have: ``` private static void RegisterSolrOperations(SolrCore core, Container container, bool isNamed = true) { var ISolrReadOnlyOperations = typeof(ISolrReadOnlyOperations<>).MakeGenericType(core.DocumentType); var ISolrBasicOperations = typeof(ISolrBasicOperations<>).MakeGenericType(core.DocumentType); var ISolrOperations = typeof(ISolrOperations<>).MakeGenericType(core.DocumentType); var SolrServer = typeof(SolrServer<>).MakeGenericType(core.DocumentType); var registrationId = isNamed ? core.Id : null; var injectionConstructor = new InjectionConstructor( new ResolvedParameter(ISolrBasicOperations, registrationId), new ResolvedParameter(typeof(IReadOnlyMappingManager)), new ResolvedParameter(typeof(IMappingValidator))); container.Register(ISolrOperations, SolrServer, registrationId, injectionConstructor); container.Register(ISolrReadOnlyOperations, SolrServer, registrationId, injectionConstructor); } ``` But the injectionConstructor lines are obviously not for simple injector. Thanks UPDATE I should have mention that I was using solrNet 0.4.x so config will be slightly different. After looking at Steven's answer I now have: ``` container.RegisterSingle<IReadOnlyMappingManager>( new MemoizingMappingManager(new AttributesMappingManager())); container.Register<ISolrDocumentPropertyVisitor, DefaultDocumentVisitor>(); container.Register<ISolrFieldParser, DefaultFieldParser>(); container.RegisterAllOpenGeneric(typeof(ISolrDocumentActivator<>), typeof(SolrDocumentActivator<>)); container.RegisterAllOpenGeneric(typeof(ISolrDocumentResponseParser<>), typeof(SolrDocumentResponseParser<>)); container.Register<ISolrFieldSerializer, DefaultFieldSerializer>(); container.Register<ISolrQuerySerializer, DefaultQuerySerializer>(); container.Register<ISolrFacetQuerySerializer, DefaultFacetQuerySerializer>(); container.RegisterAllOpenGeneric(typeof(ISolrAbstractResponseParser<>), typeof(DefaultResponseParser<>)); container.Register<ISolrHeaderResponseParser, HeaderResponseParser<string>>(); container.Register<ISolrExtractResponseParser, ExtractResponseParser>(); container.RegisterAll<IValidationRule>(new[] { typeof(MappedPropertiesIsInSolrSchemaRule), typeof(RequiredFieldsAreMappedRule), typeof(UniqueKeyMatchesMappingRule) }); container.Register<ISolrConnection>(() => new SolrConnection(url)); container.RegisterAllOpenGeneric(typeof(ISolrMoreLikeThisHandlerQueryResultsParser<>), typeof(SolrMoreLikeThisHandlerQueryResultsParser<>)); container.RegisterAllOpenGeneric(typeof(ISolrQueryExecuter<>), typeof(SolrQueryExecuter<>)); container.RegisterAllOpenGeneric(typeof(ISolrDocumentSerializer<>), typeof(SolrDocumentSerializer<>)); container.RegisterAllOpenGeneric(typeof(ISolrBasicOperations<>), typeof(SolrBasicServer<>)); container.RegisterAllOpenGeneric(typeof(ISolrBasicReadOnlyOperations<>), typeof(SolrBasicServer<>)); container.RegisterAllOpenGeneric(typeof(ISolrOperations<>), typeof(SolrServer<>)); container.RegisterAllOpenGeneric(typeof(ISolrReadOnlyOperations<>), typeof(SolrServer<>)); container.Register<ISolrSchemaParser, SolrSchemaParser>(); container.Register<ISolrDIHStatusParser, SolrDIHStatusParser>(); container.Register<IMappingValidator, MappingValidator>(); ``` but with this I get the error: The constructor of the type MappingValidator contains the parameter of type IValidationRule[] with name 'rules' that is not registered. Please ensure IValidationRule[] is registered in the container, or change the constructor of MappingValidator.

Original source