created container extension for search/lucene stuff, modified namespaces to stay in alignment with Portoa
This commit is contained in:
parent
a0c0c6791e
commit
5e15232192
@ -0,0 +1,76 @@
|
|||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Lucene.Net.Analysis;
|
||||||
|
using Lucene.Net.Analysis.Standard;
|
||||||
|
using Lucene.Net.Index;
|
||||||
|
using Lucene.Net.QueryParsers;
|
||||||
|
using Lucene.Net.Store;
|
||||||
|
using Microsoft.Practices.Unity;
|
||||||
|
using Microsoft.Practices.Unity.InterceptionExtension;
|
||||||
|
using Portoa.Lucene;
|
||||||
|
using Portoa.Persistence;
|
||||||
|
using Portoa.Search;
|
||||||
|
using Portoa.Web.Unity;
|
||||||
|
using Portoa.Web.Unity.Lifetime;
|
||||||
|
using VideoGameQuotes.Api;
|
||||||
|
using VideoGameQuotes.Web.Search;
|
||||||
|
using Directory = Lucene.Net.Store.Directory;
|
||||||
|
using Version = Lucene.Net.Util.Version;
|
||||||
|
|
||||||
|
namespace VideoGameQuotes.Web.Configuration {
|
||||||
|
public class EnableSearchWithLucene : UnityContainerExtension {
|
||||||
|
protected override void Initialize() {
|
||||||
|
var indexWriterLifetimeManager = new ExplicitlyDisposableLifetimeManager<IndexWriter>(
|
||||||
|
new ContainerControlledLifetimeManager(),
|
||||||
|
indexWriter => indexWriter.Close()
|
||||||
|
);
|
||||||
|
|
||||||
|
Container
|
||||||
|
.RegisterType<Directory>(new ContainerControlledLifetimeManager(), new InjectionFactory(CreateIndexDirectory))
|
||||||
|
.RegisterType<IndexWriter>(indexWriterLifetimeManager, new InjectionFactory(CreateIndexWriter))
|
||||||
|
.RegisterInstance(Version.LUCENE_29)
|
||||||
|
.RegisterType<Analyzer, StandardAnalyzer>(new InjectionConstructor(typeof(Version)))
|
||||||
|
.RegisterType<QueryParser>(new InjectionFactory(CreateQueryParser))
|
||||||
|
.RegisterAndIntercept(typeof(ISearcher<>), typeof(LuceneEntitySearcher<>))
|
||||||
|
.RegisterAndIntercept(typeof(ISearchService<>), typeof(SearchService<>))
|
||||||
|
.RegisterAndIntercept<ILuceneDocumentHandler<Quote>, QuoteDocumentHandler>()
|
||||||
|
.RegisterAndIntercept(typeof(ISearchIndexBuilder<>), typeof(LuceneEntityIndexBuilder<>));
|
||||||
|
|
||||||
|
Container
|
||||||
|
.Configure<Interception>()
|
||||||
|
.AddPolicy("UpdateSearchIndexPolicy")
|
||||||
|
.AddCallHandler<UpdateSearchIndexCallHandler>()
|
||||||
|
.AddMatchingRule<QuoteUpdatedMatchingRule>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region lucene-related factories
|
||||||
|
private static QueryParser CreateQueryParser(IUnityContainer container) {
|
||||||
|
return new QueryParser(container.Resolve<Version>(), "text", container.Resolve<Analyzer>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Directory CreateIndexDirectory(IUnityContainer container) {
|
||||||
|
var indexDirectory = ((NameValueCollection)ConfigurationManager.GetSection("vgquotes"))["luceneIndexDirectory"];
|
||||||
|
return new SimpleFSDirectory(new DirectoryInfo(indexDirectory));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IndexWriter CreateIndexWriter(IUnityContainer container) {
|
||||||
|
return new IndexWriter(
|
||||||
|
container.Resolve<Directory>(),
|
||||||
|
new StandardAnalyzer(Version.LUCENE_29),
|
||||||
|
true,
|
||||||
|
IndexWriter.MaxFieldLength.UNLIMITED
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public class QuoteUpdatedMatchingRule : IMatchingRule {
|
||||||
|
private static readonly MethodBase saveMethod = typeof(IRepository<Quote, int>).GetMethod("Save", new[] { typeof(Quote) });
|
||||||
|
|
||||||
|
public bool Matches(MethodBase member) {
|
||||||
|
return member == saveMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,37 +1,19 @@
|
|||||||
using System.Reflection;
|
|
||||||
using Microsoft.Practices.Unity;
|
using Microsoft.Practices.Unity;
|
||||||
using Microsoft.Practices.Unity.InterceptionExtension;
|
using Microsoft.Practices.Unity.InterceptionExtension;
|
||||||
using Portoa.Persistence;
|
|
||||||
using Portoa.Search;
|
using Portoa.Search;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Configuration {
|
namespace VideoGameQuotes.Web.Configuration {
|
||||||
|
/// <summary>
|
||||||
public class UpdateSearchIndex : UnityContainerExtension {
|
/// Call handler that updates the index for a quote whenever it's updated
|
||||||
protected override void Initialize() {
|
/// </summary>
|
||||||
Container
|
|
||||||
.Configure<Interception>()
|
|
||||||
.AddPolicy("UpdateSearchIndexPolicy")
|
|
||||||
.AddCallHandler<UpdateSearchIndexCallHandler>()
|
|
||||||
.AddMatchingRule<QuoteUpdatedMatchingRule>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class QuoteUpdatedMatchingRule : IMatchingRule {
|
|
||||||
private static readonly MethodBase saveMethod = typeof(IRepository<Quote, int>).GetMethod("Save", new[] { typeof(Quote) });
|
|
||||||
|
|
||||||
public bool Matches(MethodBase member) {
|
|
||||||
return member == saveMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UpdateSearchIndexCallHandler : ICallHandler {
|
public class UpdateSearchIndexCallHandler : ICallHandler {
|
||||||
private readonly IUnityContainer container;
|
private readonly IUnityContainer container;
|
||||||
|
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Can't inject ISearchIndexBuilder because it causes an infinite loop
|
/// Can't inject ISearchIndexBuilder because it causes an infinite loop
|
||||||
/// while trying to instantiate the call handler. So we do a later resolve
|
/// while trying to instantiate the call handler. So we do a later resolve
|
||||||
/// on the index builder so that this shit fucking works.
|
/// using the container on the index builder so that this shit fucking works.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public UpdateSearchIndexCallHandler(IUnityContainer container) {
|
public UpdateSearchIndexCallHandler(IUnityContainer container) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
using Portoa.Web;
|
|
||||||
using Portoa.Web.ErrorHandling;
|
using Portoa.Web.ErrorHandling;
|
||||||
using Portoa.Web.Results;
|
using Portoa.Web.Results;
|
||||||
|
using Portoa.Web.Security;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
using VideoGameQuotes.Web.Security;
|
using VideoGameQuotes.Web.Security;
|
||||||
@ -121,7 +121,7 @@ namespace VideoGameQuotes.Web.Controllers {
|
|||||||
adminService.SaveUser(user);
|
adminService.SaveUser(user);
|
||||||
return View("PasswordSuccessfullyChanged");
|
return View("PasswordSuccessfullyChanged");
|
||||||
} catch {
|
} catch {
|
||||||
ControllerContext.AddModelError("password", "Unable to change password");
|
ModelState.AddModelError("password", "Unable to change password");
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ using System.Linq;
|
|||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
using Portoa.Util;
|
using Portoa.Util;
|
||||||
using Portoa.Web;
|
|
||||||
using Portoa.Web.Controllers;
|
using Portoa.Web.Controllers;
|
||||||
|
using Portoa.Web.Security;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
using VideoGameQuotes.Web.Security;
|
using VideoGameQuotes.Web.Security;
|
||||||
|
@ -5,9 +5,9 @@ using System.Web.Mvc;
|
|||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
using Portoa.Search;
|
using Portoa.Search;
|
||||||
using Portoa.Validation.DataAnnotations;
|
using Portoa.Validation.DataAnnotations;
|
||||||
using Portoa.Web;
|
|
||||||
using Portoa.Web.Controllers;
|
using Portoa.Web.Controllers;
|
||||||
using Portoa.Web.Results;
|
using Portoa.Web.Results;
|
||||||
|
using Portoa.Web.Security;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
using VideoGameQuotes.Web.Security;
|
using VideoGameQuotes.Web.Security;
|
||||||
|
@ -1,20 +1,7 @@
|
|||||||
using System.Collections.Specialized;
|
using System.Web.Mvc;
|
||||||
using System.Configuration;
|
|
||||||
using System.IO;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using Lucene.Net.Analysis;
|
|
||||||
using Lucene.Net.Analysis.Standard;
|
|
||||||
using Lucene.Net.Index;
|
using Lucene.Net.Index;
|
||||||
using Lucene.Net.QueryParsers;
|
|
||||||
using Lucene.Net.Search;
|
|
||||||
using Lucene.Net.Store;
|
|
||||||
using Lucene.Net.Util;
|
|
||||||
using Microsoft.Practices.Unity;
|
using Microsoft.Practices.Unity;
|
||||||
using Microsoft.Practices.Unity.InterceptionExtension;
|
|
||||||
using Portoa.Logging;
|
|
||||||
using Portoa.Lucene;
|
|
||||||
using Portoa.Persistence;
|
|
||||||
using Portoa.Search;
|
using Portoa.Search;
|
||||||
using Portoa.Web;
|
using Portoa.Web;
|
||||||
using Portoa.Web.Models;
|
using Portoa.Web.Models;
|
||||||
@ -26,14 +13,11 @@ using VideoGameQuotes.Api.Persistence;
|
|||||||
using VideoGameQuotes.Web.Configuration;
|
using VideoGameQuotes.Web.Configuration;
|
||||||
using VideoGameQuotes.Web.Controllers;
|
using VideoGameQuotes.Web.Controllers;
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
using VideoGameQuotes.Web.Search;
|
|
||||||
using VideoGameQuotes.Web.Security;
|
using VideoGameQuotes.Web.Security;
|
||||||
using VideoGameQuotes.Web.Services;
|
using VideoGameQuotes.Web.Services;
|
||||||
using Directory = Lucene.Net.Store.Directory;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web {
|
namespace VideoGameQuotes.Web {
|
||||||
public class MvcApplication : MvcApplicationBase<User> {
|
public class MvcApplication : MvcApplicationBase<User> {
|
||||||
|
|
||||||
protected override void ConfigureModelBinders(ModelBinderDictionary binders) {
|
protected override void ConfigureModelBinders(ModelBinderDictionary binders) {
|
||||||
binders
|
binders
|
||||||
.Add<Region, FlagEnumModelBinder<Region>>()
|
.Add<Region, FlagEnumModelBinder<Region>>()
|
||||||
@ -41,18 +25,13 @@ namespace VideoGameQuotes.Web {
|
|||||||
.Add<ApiModel, ApiModelBinder>();
|
.Add<ApiModel, ApiModelBinder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ConfigureUnityExtensions() {
|
protected override void ConfigureUnity() {
|
||||||
Container
|
Container
|
||||||
.AddNewExtension<ConfigureLog4Net>()
|
.AddNewExtension<ConfigureLog4Net>()
|
||||||
.Configure<ILog4NetConfigurator>()
|
.Configure<ILog4NetConfigurator>()
|
||||||
.SetName("VideoGameQuotes.Web")
|
.SetName("VideoGameQuotes.Web")
|
||||||
.UseXml();
|
.UseXml();
|
||||||
|
|
||||||
Container.AddNewExtension<LogAllMethodCalls>();
|
|
||||||
Container.AddNewExtension<UpdateSearchIndex>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ConfigureUnity() {
|
|
||||||
Container
|
Container
|
||||||
.RegisterType<VerifyUserAttribute>(new InjectionProperty<VerifyUserAttribute>(attr => attr.UserProvider))
|
.RegisterType<VerifyUserAttribute>(new InjectionProperty<VerifyUserAttribute>(attr => attr.UserProvider))
|
||||||
.RegisterAndIntercept<ICurrentUserProvider<User>, SessionBasedUserProvider>()
|
.RegisterAndIntercept<ICurrentUserProvider<User>, SessionBasedUserProvider>()
|
||||||
@ -65,45 +44,19 @@ namespace VideoGameQuotes.Web {
|
|||||||
.RegisterAndIntercept<IGameService, GameService>()
|
.RegisterAndIntercept<IGameService, GameService>()
|
||||||
.RegisterAndIntercept<IApiService, ApiService>()
|
.RegisterAndIntercept<IApiService, ApiService>()
|
||||||
.RegisterAndIntercept<IAuthenticationService, FormsAuthenticationService>()
|
.RegisterAndIntercept<IAuthenticationService, FormsAuthenticationService>()
|
||||||
.RegisterAndIntercept<IUserRepository, UserRepository>();
|
.RegisterAndIntercept<IUserRepository, UserRepository>()
|
||||||
|
.AddNewExtension<LogAllMethodCalls>()
|
||||||
//search stuff
|
.AddNewExtension<EnableSearchWithLucene>();
|
||||||
Container
|
|
||||||
.RegisterType<Directory>(new ContainerControlledLifetimeManager(), new InjectionFactory(CreateIndexDirectory))
|
|
||||||
.RegisterType<IndexWriter>(new ContainerControlledLifetimeManager(), new InjectionFactory(CreateIndexWriter))
|
|
||||||
.RegisterInstance(Version.LUCENE_29)
|
|
||||||
.RegisterType<Analyzer, StandardAnalyzer>(new InjectionConstructor(typeof(Version)))
|
|
||||||
.RegisterType<QueryParser>(new InjectionFactory(CreateQueryParser))
|
|
||||||
.RegisterAndIntercept(typeof(ISearcher<>), typeof(LuceneEntitySearcher<>))
|
|
||||||
.RegisterAndIntercept(typeof(ISearchService<>), typeof(SearchService<>))
|
|
||||||
.RegisterAndIntercept<ILuceneDocumentHandler<Quote>, QuoteDocumentHandler>()
|
|
||||||
.RegisterAndIntercept(typeof(ISearchIndexBuilder<>), typeof(LuceneEntityIndexBuilder<>));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region lucene-related factories
|
|
||||||
private static QueryParser CreateQueryParser(IUnityContainer container) {
|
|
||||||
return new QueryParser(container.Resolve<Version>(), "text", container.Resolve<Analyzer>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Directory CreateIndexDirectory(IUnityContainer container) {
|
|
||||||
var indexDirectory = ((NameValueCollection)ConfigurationManager.GetSection("vgquotes"))["luceneIndexDirectory"];
|
|
||||||
return new SimpleFSDirectory(new DirectoryInfo(indexDirectory));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IndexWriter CreateIndexWriter(IUnityContainer container) {
|
|
||||||
return new IndexWriter(
|
|
||||||
container.Resolve<Directory>(),
|
|
||||||
new StandardAnalyzer(Version.LUCENE_29),
|
|
||||||
true,
|
|
||||||
IndexWriter.MaxFieldLength.UNLIMITED
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
protected override void AfterStartUp() {
|
protected override void AfterStartUp() {
|
||||||
Container.Resolve<ISearchIndexBuilder<Quote>>().BuildIndex();
|
Container.Resolve<ISearchIndexBuilder<Quote>>().BuildIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnApplicationEnd() {
|
||||||
|
Container.Resolve<IndexWriter>().Close();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void RegisterRoutes(RouteCollection routes) {
|
protected override void RegisterRoutes(RouteCollection routes) {
|
||||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||||
routes.IgnoreRoute("media/{*anything}");
|
routes.IgnoreRoute("media/{*anything}");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Portoa.Web;
|
using Portoa.Web.Util;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Models {
|
namespace VideoGameQuotes.Web.Models {
|
||||||
public class ApiModel {
|
public class ApiModel {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Portoa.Web;
|
using Portoa.Web.Util;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Models {
|
namespace VideoGameQuotes.Web.Models {
|
||||||
public class BrowseModelBinder : IModelBinder {
|
public class BrowseModelBinder : IModelBinder {
|
||||||
|
@ -4,7 +4,6 @@ using Portoa.Persistence;
|
|||||||
using Portoa.Search;
|
using Portoa.Search;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Search {
|
namespace VideoGameQuotes.Web.Search {
|
||||||
|
|
||||||
public class SearchService<T> : ISearchService<T> where T : Entity<T, int> {
|
public class SearchService<T> : ISearchService<T> where T : Entity<T, int> {
|
||||||
private readonly IRepository<T> repository;
|
private readonly IRepository<T> repository;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using Portoa.Web;
|
using Portoa.Web.Security;
|
||||||
using Portoa.Web.Session;
|
using Portoa.Web.Session;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Api.Persistence;
|
using VideoGameQuotes.Api.Persistence;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Portoa.Web;
|
|
||||||
using Portoa.Web.ErrorHandling;
|
using Portoa.Web.ErrorHandling;
|
||||||
|
using Portoa.Web.Security;
|
||||||
|
using Portoa.Web.Unity;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Security {
|
namespace VideoGameQuotes.Web.Security {
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Configuration\EnableSearchWithLucene.cs" />
|
||||||
<Compile Include="Configuration\UpdateSearchIndexCallHandler.cs" />
|
<Compile Include="Configuration\UpdateSearchIndexCallHandler.cs" />
|
||||||
<Compile Include="Controllers\AdminController.cs" />
|
<Compile Include="Controllers\AdminController.cs" />
|
||||||
<Compile Include="Controllers\ApiController.cs" />
|
<Compile Include="Controllers\ApiController.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user