Skip to content

Commit

Permalink
added SimpleInjector support
Browse files Browse the repository at this point in the history
- added module to support Simple Injector
  • Loading branch information
João Martins committed Jul 29, 2018
1 parent ab2599a commit f0d8335
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 2 deletions.
22 changes: 22 additions & 0 deletions SimpleInjector.SolrNet.Tests/SimpleInjector.SolrNet.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net46</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
<PackageReference Include="SimpleInjector" Version="4.3.0" />
<PackageReference Include="SolrNet.Core" Version="1.0.9" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SimpleInjector.SolrNet\SimpleInjector.SolrNet.csproj" />
</ItemGroup>

</Project>
89 changes: 89 additions & 0 deletions SimpleInjector.SolrNet.Tests/SimpleInjectorFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using SolrNet;
using SolrNet.Impl;
using System;
using Xunit;

namespace SimpleInjector.SolrNet.Tests
{
public class SimpleInjectorFixture
{
private readonly Container Container;

public SimpleInjectorFixture()
{
Container = new Container();
Container.AddSolrNet("http://localhost:8983/solr");
}

[Fact]
public void ResolveIReadOnlyMappingManager()
{
var mapper = Container.GetInstance<IReadOnlyMappingManager>();
Assert.NotNull(mapper);
}


[Fact]
public void ResolveSolrDocumentActivator()
{
var solr = Container.GetInstance<ISolrDocumentActivator<Entity>>();
Assert.NotNull(solr);
}

[Fact]
public void ResolveSolrAbstractResponseParser()
{
var solr = Container.GetInstance<ISolrAbstractResponseParser<Entity>>();
Assert.NotNull(solr);
}


[Fact]
public void ResolveSolrAbstractResponseParsersViaEnumerable()
{
var result = Container.GetAllInstances<ISolrAbstractResponseParser<Entity>>();
Assert.NotNull(result);
Assert.Single(result);

}

[Fact]
public void ResolveSolrMoreLikeThisHandlerQueryResultsParser()
{
var solr = Container.GetInstance<ISolrMoreLikeThisHandlerQueryResultsParser<Entity>>();
Assert.NotNull(solr);
}


[Fact]
public void ResolveSolrOperations()
{
var solr = Container.GetInstance<ISolrOperations<Entity>>();
Assert.NotNull(solr);
}



[Fact]
public void SetBasicAuthenticationHeader()
{
var c = new Container();

//my credentials
var credentials = System.Text.Encoding.ASCII.GetBytes("myUsername:myPassword");
//in base64
var credentialsBase64 = Convert.ToBase64String(credentials);
//use the options to set the Authorization header.
c.AddSolrNet("http://localhost:8983/solr", options => { options.HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentialsBase64); });

//test
var connection = c.GetInstance<ISolrConnection>() as AutoSolrConnection;

Assert.NotNull(connection.HttpClient.DefaultRequestHeaders.Authorization);
Assert.Equal(credentialsBase64, connection.HttpClient.DefaultRequestHeaders.Authorization.Parameter);
}

public class Entity { }

}
}
37 changes: 37 additions & 0 deletions SimpleInjector.SolrNet.Tests/SimpleInjectorIntegrationFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using SolrNet;
using System;
using Xunit;
using static SimpleInjector.SolrNet.Tests.SimpleInjectorFixture;

namespace SimpleInjector.SolrNet.Tests
{
[Trait("Category", "Integration")]
public class SimpleInjectorIntegrationFixture
{
private readonly Container Container;

public SimpleInjectorIntegrationFixture()
{
Container = new Container();

// collection needs to exist
Container.AddSolrNet("http://localhost:8983/solr/FilesCollection");
}

[Fact]
public void Ping_And_Query()
{
var solr = Container.GetInstance<ISolrOperations<Entity>>();
solr.Ping();
Console.WriteLine(solr.Query(SolrQuery.All).Count);
}

[Fact]
public void Ping_And_Query_SingleCore()
{
var solr = Container.GetInstance<ISolrOperations<Entity>>();
solr.Ping();
Console.WriteLine(solr.Query(SolrQuery.All).Count);
}
}
}
89 changes: 89 additions & 0 deletions SimpleInjector.SolrNet/ContainerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using SolrNet;
using SolrNet.Impl;
using SolrNet.Impl.DocumentPropertyVisitors;
using SolrNet.Impl.FacetQuerySerializers;
using SolrNet.Impl.FieldParsers;
using SolrNet.Impl.FieldSerializers;
using SolrNet.Impl.QuerySerializers;
using SolrNet.Impl.ResponseParsers;
using SolrNet.Mapping;
using SolrNet.Mapping.Validation;
using SolrNet.Mapping.Validation.Rules;
using SolrNet.Schema;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SimpleInjector.SolrNet
{
public static class ContainerExtensions
{
public static Container AddSolrNet(this Container container, string url)
{
if (container == null) throw new ArgumentNullException(nameof(container));

return container.AddSolrNet(new SolrCore[] { new SolrCore(null, null, url) }, null);
}

public static Container AddSolrNet(this Container container, string url, Action<SolrNetOptions> setupAction) => AddSolrNet(container, new SolrCore[] { new SolrCore(null, null, url) }, setupAction);

private static Container AddSolrNet(this Container container, IEnumerable<SolrCore> cores, Action<SolrNetOptions> setupAction)
{
if (container == null) throw new ArgumentNullException(nameof(container));

container.Register<IReadOnlyMappingManager, AttributesMappingManager>(Lifestyle.Singleton);
container.Register<ISolrDocumentPropertyVisitor, DefaultDocumentVisitor>(Lifestyle.Transient);
container.Register<ISolrFieldParser, DefaultFieldParser>(Lifestyle.Transient);
container.Register(typeof(ISolrDocumentActivator<>), typeof(SolrDocumentActivator<>), Lifestyle.Transient);
container.RegisterConditional(typeof(ISolrDocumentResponseParser<>), typeof(SolrDocumentResponseParser<>), c => !c.Handled);

container.Register<ISolrDocumentResponseParser<Dictionary<string, object>>, SolrDictionaryDocumentResponseParser>(Lifestyle.Transient);
container.Register<ISolrFieldSerializer, DefaultFieldSerializer>(Lifestyle.Transient);
container.Register<ISolrQuerySerializer, DefaultQuerySerializer>(Lifestyle.Transient);
container.Register<ISolrFacetQuerySerializer, DefaultFacetQuerySerializer>(Lifestyle.Transient);
container.Register(typeof(ISolrAbstractResponseParser<>), typeof(DefaultResponseParser<>), Lifestyle.Transient);
container.Collection.Register(typeof(ISolrAbstractResponseParser<>), new[] { typeof(DefaultResponseParser<>) });
container.Register<ISolrHeaderResponseParser, HeaderResponseParser<string>>(Lifestyle.Transient);
container.Register<ISolrExtractResponseParser, ExtractResponseParser>(Lifestyle.Transient);
var p = new[] {
typeof(MappedPropertiesIsInSolrSchemaRule),
typeof(RequiredFieldsAreMappedRule),
typeof(UniqueKeyMatchesMappingRule),
typeof(MultivaluedMappedToCollectionRule),
};
container.Collection.Register(typeof(IValidationRule), p);
container.Register(typeof(ISolrMoreLikeThisHandlerQueryResultsParser<>), typeof(SolrMoreLikeThisHandlerQueryResultsParser<>), Lifestyle.Transient);
container.RegisterConditional(typeof(ISolrDocumentSerializer<>), typeof(SolrDocumentSerializer<>), c => !c.Handled);
container.Register<ISolrDocumentSerializer<Dictionary<string, object>>, SolrDictionarySerializer>(Lifestyle.Transient);

container.Register<ISolrSchemaParser, SolrSchemaParser>(Lifestyle.Transient);
container.Register<ISolrDIHStatusParser, SolrDIHStatusParser>(Lifestyle.Transient);
container.Register<IMappingValidator, MappingValidator>(Lifestyle.Transient);

if (!cores.Any()) return container;

if (cores.Count() > 1)
{
throw new NotImplementedException("Need to add multicore support");
}

var connection = new AutoSolrConnection(cores.Single().Url);
//Bind single type to a single url, prevent breaking existing functionality
container.Register<ISolrConnection>(() => connection, Lifestyle.Singleton);
container.Register(typeof(ISolrQueryExecuter<>), typeof(SolrQueryExecuter<>), Lifestyle.Transient);
container.Register(typeof(ISolrBasicOperations<>), typeof(SolrBasicServer<>), Lifestyle.Transient);
container.Register(typeof(ISolrBasicReadOnlyOperations<>), typeof(SolrBasicServer<>), Lifestyle.Transient);
container.Register(typeof(ISolrOperations<>), typeof(SolrServer<>), Lifestyle.Transient);
container.Register(typeof(ISolrReadOnlyOperations<>), typeof(SolrServer<>), Lifestyle.Transient);

if (setupAction != null)
{
var options = new SolrNetOptions(connection.HttpClient);
//allow for custom headers to be injected.
setupAction(options);
}

return container;
}
}
}
12 changes: 12 additions & 0 deletions SimpleInjector.SolrNet/SimpleInjector.SolrNet.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SimpleInjector" Version="4.3.0" />
<PackageReference Include="SolrNet.Core" Version="1.0.9" />
</ItemGroup>

</Project>
18 changes: 18 additions & 0 deletions SimpleInjector.SolrNet/SolrCore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace SimpleInjector.SolrNet
{
internal class SolrCore
{
public string Id { get; private set; }
public string Url { get; private set; }
public Type DocumentType { get; private set; }

public SolrCore(string id, Type documentType, string url)
{
Id = id;
DocumentType = documentType;
Url = url;
}
}
}
17 changes: 17 additions & 0 deletions SimpleInjector.SolrNet/SolrNetOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Net.Http;

namespace SimpleInjector.SolrNet
{
public class SolrNetOptions
{
public SolrNetOptions(HttpClient httpClient)
{
HttpClient = httpClient;
}

/// <summary>
/// Gets the HttpClient with which SolrNet connects to the Solr server. This is the place to add Default Headers for Basic Authentication for example..
/// </summary>
public HttpClient HttpClient { get; }
}
}
17 changes: 15 additions & 2 deletions SolrNet.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
VisualStudioVersion = 15.0.26730.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SolrNet", "SolrNet\SolrNet.csproj", "{CEEB8690-3E08-4440-B647-787A58E71CFA}"
EndProject
Expand Down Expand Up @@ -62,6 +62,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SolrNet.Tests.Common", "Sol
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C167AD0C-270B-4297-94C5-BE5548AA6038}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleInjector.SolrNet.Tests", "SimpleInjector.SolrNet.Tests\SimpleInjector.SolrNet.Tests.csproj", "{110F4D69-8F08-42F5-97DB-B0A42B3107AC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleInjector.SolrNet", "SimpleInjector.SolrNet\SimpleInjector.SolrNet.csproj", "{D1A5AF1A-CB44-4079-85C6-08D8F74CFF21}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -172,6 +176,14 @@ Global
{48DA5170-B96E-485C-941D-0D7797DCA0EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48DA5170-B96E-485C-941D-0D7797DCA0EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48DA5170-B96E-485C-941D-0D7797DCA0EF}.Release|Any CPU.Build.0 = Release|Any CPU
{110F4D69-8F08-42F5-97DB-B0A42B3107AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{110F4D69-8F08-42F5-97DB-B0A42B3107AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{110F4D69-8F08-42F5-97DB-B0A42B3107AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{110F4D69-8F08-42F5-97DB-B0A42B3107AC}.Release|Any CPU.Build.0 = Release|Any CPU
{D1A5AF1A-CB44-4079-85C6-08D8F74CFF21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1A5AF1A-CB44-4079-85C6-08D8F74CFF21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1A5AF1A-CB44-4079-85C6-08D8F74CFF21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1A5AF1A-CB44-4079-85C6-08D8F74CFF21}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -190,9 +202,10 @@ Global
{0988D6A2-04FD-4328-AFFA-677DB377432D} = {C167AD0C-270B-4297-94C5-BE5548AA6038}
{C4FF031C-FB88-4186-9305-B180A07EC7DA} = {C167AD0C-270B-4297-94C5-BE5548AA6038}
{48DA5170-B96E-485C-941D-0D7797DCA0EF} = {C167AD0C-270B-4297-94C5-BE5548AA6038}
{110F4D69-8F08-42F5-97DB-B0A42B3107AC} = {C167AD0C-270B-4297-94C5-BE5548AA6038}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BC12CF2E-A108-47A2-B60C-A17B3102D52D}
EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.Common.6.0.1304.0\lib\NET45
SolutionGuid = {BC12CF2E-A108-47A2-B60C-A17B3102D52D}
EndGlobalSection
EndGlobal

0 comments on commit f0d8335

Please sign in to comment.