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.InterceptionExtension;
|
||||
using Portoa.Persistence;
|
||||
using Portoa.Search;
|
||||
using VideoGameQuotes.Api;
|
||||
|
||||
namespace VideoGameQuotes.Web.Configuration {
|
||||
|
||||
public class UpdateSearchIndex : UnityContainerExtension {
|
||||
protected override void Initialize() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call handler that updates the index for a quote whenever it's updated
|
||||
/// </summary>
|
||||
public class UpdateSearchIndexCallHandler : ICallHandler {
|
||||
private readonly IUnityContainer container;
|
||||
|
||||
/// <remarks>
|
||||
/// Can't inject ISearchIndexBuilder because it causes an infinite loop
|
||||
/// 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>
|
||||
public UpdateSearchIndexCallHandler(IUnityContainer container) {
|
||||
this.container = container;
|
||||
|
@ -2,9 +2,9 @@
|
||||
using System.Net;
|
||||
using System.Web.Mvc;
|
||||
using Portoa.Persistence;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.ErrorHandling;
|
||||
using Portoa.Web.Results;
|
||||
using Portoa.Web.Security;
|
||||
using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Web.Models;
|
||||
using VideoGameQuotes.Web.Security;
|
||||
@ -121,7 +121,7 @@ namespace VideoGameQuotes.Web.Controllers {
|
||||
adminService.SaveUser(user);
|
||||
return View("PasswordSuccessfullyChanged");
|
||||
} catch {
|
||||
ControllerContext.AddModelError("password", "Unable to change password");
|
||||
ModelState.AddModelError("password", "Unable to change password");
|
||||
return View(model);
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@ using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Portoa.Persistence;
|
||||
using Portoa.Util;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.Controllers;
|
||||
using Portoa.Web.Security;
|
||||
using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Web.Models;
|
||||
using VideoGameQuotes.Web.Security;
|
||||
|
@ -5,9 +5,9 @@ using System.Web.Mvc;
|
||||
using Portoa.Persistence;
|
||||
using Portoa.Search;
|
||||
using Portoa.Validation.DataAnnotations;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.Controllers;
|
||||
using Portoa.Web.Results;
|
||||
using Portoa.Web.Security;
|
||||
using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Web.Models;
|
||||
using VideoGameQuotes.Web.Security;
|
||||
|
@ -1,20 +1,7 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Analysis.Standard;
|
||||
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.InterceptionExtension;
|
||||
using Portoa.Logging;
|
||||
using Portoa.Lucene;
|
||||
using Portoa.Persistence;
|
||||
using Portoa.Search;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.Models;
|
||||
@ -26,14 +13,11 @@ using VideoGameQuotes.Api.Persistence;
|
||||
using VideoGameQuotes.Web.Configuration;
|
||||
using VideoGameQuotes.Web.Controllers;
|
||||
using VideoGameQuotes.Web.Models;
|
||||
using VideoGameQuotes.Web.Search;
|
||||
using VideoGameQuotes.Web.Security;
|
||||
using VideoGameQuotes.Web.Services;
|
||||
using Directory = Lucene.Net.Store.Directory;
|
||||
|
||||
namespace VideoGameQuotes.Web {
|
||||
public class MvcApplication : MvcApplicationBase<User> {
|
||||
|
||||
protected override void ConfigureModelBinders(ModelBinderDictionary binders) {
|
||||
binders
|
||||
.Add<Region, FlagEnumModelBinder<Region>>()
|
||||
@ -41,18 +25,13 @@ namespace VideoGameQuotes.Web {
|
||||
.Add<ApiModel, ApiModelBinder>();
|
||||
}
|
||||
|
||||
protected override void ConfigureUnityExtensions() {
|
||||
protected override void ConfigureUnity() {
|
||||
Container
|
||||
.AddNewExtension<ConfigureLog4Net>()
|
||||
.Configure<ILog4NetConfigurator>()
|
||||
.SetName("VideoGameQuotes.Web")
|
||||
.UseXml();
|
||||
|
||||
Container.AddNewExtension<LogAllMethodCalls>();
|
||||
Container.AddNewExtension<UpdateSearchIndex>();
|
||||
}
|
||||
|
||||
protected override void ConfigureUnity() {
|
||||
Container
|
||||
.RegisterType<VerifyUserAttribute>(new InjectionProperty<VerifyUserAttribute>(attr => attr.UserProvider))
|
||||
.RegisterAndIntercept<ICurrentUserProvider<User>, SessionBasedUserProvider>()
|
||||
@ -65,45 +44,19 @@ namespace VideoGameQuotes.Web {
|
||||
.RegisterAndIntercept<IGameService, GameService>()
|
||||
.RegisterAndIntercept<IApiService, ApiService>()
|
||||
.RegisterAndIntercept<IAuthenticationService, FormsAuthenticationService>()
|
||||
.RegisterAndIntercept<IUserRepository, UserRepository>();
|
||||
|
||||
//search stuff
|
||||
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<>));
|
||||
.RegisterAndIntercept<IUserRepository, UserRepository>()
|
||||
.AddNewExtension<LogAllMethodCalls>()
|
||||
.AddNewExtension<EnableSearchWithLucene>();
|
||||
}
|
||||
|
||||
#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() {
|
||||
Container.Resolve<ISearchIndexBuilder<Quote>>().BuildIndex();
|
||||
}
|
||||
|
||||
protected override void OnApplicationEnd() {
|
||||
Container.Resolve<IndexWriter>().Close();
|
||||
}
|
||||
|
||||
protected override void RegisterRoutes(RouteCollection routes) {
|
||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||
routes.IgnoreRoute("media/{*anything}");
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.Util;
|
||||
|
||||
namespace VideoGameQuotes.Web.Models {
|
||||
public class ApiModel {
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.Util;
|
||||
|
||||
namespace VideoGameQuotes.Web.Models {
|
||||
public class BrowseModelBinder : IModelBinder {
|
||||
|
@ -4,7 +4,6 @@ using Portoa.Persistence;
|
||||
using Portoa.Search;
|
||||
|
||||
namespace VideoGameQuotes.Web.Search {
|
||||
|
||||
public class SearchService<T> : ISearchService<T> where T : Entity<T, int> {
|
||||
private readonly IRepository<T> repository;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System.Web;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.Security;
|
||||
using Portoa.Web.Session;
|
||||
using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Api.Persistence;
|
||||
|
@ -1,7 +1,8 @@
|
||||
using System.Net;
|
||||
using System.Web.Mvc;
|
||||
using Portoa.Web;
|
||||
using Portoa.Web.ErrorHandling;
|
||||
using Portoa.Web.Security;
|
||||
using Portoa.Web.Unity;
|
||||
using VideoGameQuotes.Api;
|
||||
|
||||
namespace VideoGameQuotes.Web.Security {
|
||||
|
@ -81,6 +81,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Configuration\EnableSearchWithLucene.cs" />
|
||||
<Compile Include="Configuration\UpdateSearchIndexCallHandler.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Controllers\ApiController.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user