Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Injector and SolrNet

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.

like image 780
matt_lethargic Avatar asked Feb 14 '14 16:02

matt_lethargic


1 Answers

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>();
}
like image 163
Steven Avatar answered Oct 17 '22 09:10

Steven