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( new ContainerControlledLifetimeManager(), indexWriter => indexWriter.Close() ); Container .RegisterType(new ContainerControlledLifetimeManager(), new InjectionFactory(CreateIndexDirectory)) .RegisterType(indexWriterLifetimeManager, new InjectionFactory(CreateIndexWriter)) .RegisterInstance(Version.LUCENE_29) .RegisterType(new InjectionConstructor(typeof(Version))) .RegisterType(new InjectionFactory(CreateQueryParser)) .RegisterAndIntercept(typeof(ISearcher<,>), typeof(LuceneEntitySearcher<,>)) .RegisterAndIntercept(typeof(ISearchService<,>), typeof(SearchService<,>)) .RegisterAndIntercept, QuoteDocumentHandler>() .RegisterAndIntercept(typeof(ISearchIndexBuilder<,>), typeof(LuceneEntityIndexBuilder<,>)); Container .Configure() .AddPolicy("UpdateSearchIndexPolicy") .AddCallHandler() .AddMatchingRule(new QuoteUpdatedMatchingRule()); Container .Configure() .AddPolicy("DeleteSearchIndexPolicy") .AddCallHandler() .AddMatchingRule(new QuoteDeletedMatchingRule()); } #region lucene-related factories private static QueryParser CreateQueryParser(IUnityContainer container) { return new QueryParser(container.Resolve(), "text", container.Resolve()); } 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(), container.Resolve(), true, IndexWriter.MaxFieldLength.UNLIMITED); } #endregion #region matching rules private class QuoteUpdatedMatchingRule : IMatchingRule { private static readonly MethodBase saveMethod = typeof(IRepository).GetMethod("Save", new[] { typeof(Quote) }); public bool Matches(MethodBase member) { return member == saveMethod; } } private class QuoteDeletedMatchingRule : IMatchingRule { private static readonly MethodBase deleteMethod = typeof(IRepository).GetMethod("Delete", new[] { typeof(int) }); public bool Matches(MethodBase member) { return member == deleteMethod; } } #endregion } }