<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Laurent Kempé : C#</title><link>http://weblogs.asp.net/lkempe/archive/tags/C_2300_/default.aspx</link><description>Tags: C#</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Indexing and searching business entities using Lucene.Net Framework, part 3</title><link>http://weblogs.asp.net/lkempe/archive/2008/03/07/indexing-and-searching-business-entities-using-lucene-net-framework-part-3.aspx</link><pubDate>Fri, 07 Mar 2008 10:59:25 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5932595</guid><dc:creator>lkempe</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/lkempe/rsscomments.aspx?PostID=5932595</wfw:commentRss><comments>http://weblogs.asp.net/lkempe/archive/2008/03/07/indexing-and-searching-business-entities-using-lucene-net-framework-part-3.aspx#comments</comments><description>&lt;p&gt;&lt;em&gt;&lt;img src="http://farm3.static.flickr.com/2032/2105387404_33d2e9ed92_o.gif"&gt; &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Conception using generics and reflection of a search engine to index and search content in your business entities without being intrusive.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Part 1 and 2 are available following those links&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://weblogs.asp.net/lkempe/archive/2007/11/16/indexing-and-searching-business-entities-using-lucene-net-framework-part-1.aspx"&gt;Indexing and searching business entities using Lucene.Net Framework, part 1&lt;/a&gt;  &lt;li&gt;&lt;a href="http://weblogs.asp.net/lkempe/archive/2008/03/07/indexing-and-searching-business-entities-using-lucene-net-framework-part-2.aspx"&gt;Indexing and searching business entities using Lucene.Net Framework, part 2&lt;/a&gt; &lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;&lt;a name="1.section"&gt;Solution’s architecture&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;The main idea is to be able to define the business entity’s properties that must be indexed when this one is saved or updated in the chosen persistence system.&lt;/p&gt; &lt;p&gt;With the goal to be the less intrusive possible in our model we come fast to the idea that we need to extend our business entities with meta-data. The issue then is that at runtime it is needed to know which meta-data needs to searched in the entity in order to be able to index the content of the decorated property. &lt;/p&gt; &lt;p&gt;As one of the goal is to have a Framework which manage the indexation and the searching of whatever business entity, we might have wrote a simple class inheriting from &lt;strong&gt;System.Attribute&lt;/strong&gt; in an assembly separated from our domain. That would have the drawback of behind much intrusive in our domain. Another solution was needed.&lt;/p&gt; &lt;p&gt;As we have seen the developed Framework needs to know the meta-data, giving it the opportunity to index the content of the property at runtime. This means that at development time it is absolutely possible to generalize this information by using the generics of the .NET Framework 2. As we are talking about meta-data the only imposed thing is that our class inherits from &lt;strong&gt;System.Attribute&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;The choice was made then to define a utility class in the domain assembly inheriting from &lt;strong&gt;System.Attribute&lt;/strong&gt; which will serve us as a decorator of the entity’s properties needing to be indexed.&lt;/p&gt; &lt;p&gt;On the following picture you can see an example of the domain for an application to which we have added our attribute &lt;strong&gt;&lt;em&gt;SearchableAttribute&lt;/em&gt;&lt;/strong&gt; used to decorate the Post and Page classes:&lt;/p&gt; &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2178/2316520178_1bd4bce729_o_d.jpg"&gt; &lt;/p&gt; &lt;p&gt;The Visual Studio solution is organized as a Domain Driven Development solution:&lt;/p&gt; &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2334/2316520202_3f74d3c57a_o_d.jpg"&gt; &lt;/p&gt; &lt;p&gt;We have so defined the new attribute &lt;strong&gt;&lt;em&gt;SearchableAttribute&lt;/em&gt;&lt;/strong&gt; in the assembly &lt;em&gt;innoveo.Blog.Domain&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Here is the description of the organization of our solution:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;innoveo.Blog.DAL&lt;/strong&gt;: Data access layer using &lt;a href="http://euss.evaluant.com/"&gt;Euss&lt;/a&gt; OR/M mapping tool  &lt;li&gt;&lt;strong&gt;innoveo.Blog.Domain&lt;/strong&gt;: Assembly containing our domain business entities  &lt;li&gt;&lt;strong&gt;innoveo.Blog.Services&lt;/strong&gt;: Layer exposing the different business services  &lt;li&gt;&lt;strong&gt;innoveo.Blog.Web&lt;/strong&gt;: Web presentation &amp;amp; web services layer  &lt;li&gt;&lt;strong&gt;Blog&lt;/strong&gt;: The web application &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Here it is for our solution that will use our business entities indexing Framework. Let’s have a closer look now at the Framework itself!&lt;/p&gt; &lt;h4&gt;&lt;a name="1.subsection"&gt;Indexing Framework&lt;/a&gt;&lt;/h4&gt; &lt;p&gt;First here is the class diagram:&lt;/p&gt; &lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3051/2315711785_f322531748_o_d.jpg"&gt; &lt;/p&gt; &lt;p&gt;The role of each class of our Framework is as following:  &lt;ul&gt; &lt;li&gt;&lt;strong&gt;EntityIndexer&lt;/strong&gt; manage an index and index the business entities  &lt;li&gt;&lt;strong&gt;EntitySearcher&lt;/strong&gt; let you search business entities  &lt;li&gt;&lt;strong&gt;EntityDocument&lt;/strong&gt; is used by the class EntityIndexer in order to manage Lucene.Net Document  &lt;li&gt;&lt;strong&gt;IndexPath&lt;/strong&gt; is an utility class used to specify the location of index&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As you can see on the diagram we use the .NET Frameworks 2 generics this in order to allow us to search whatever attribute decorating our business entities. But also to be able to have a Framework that is not dependant of any entities. This brings a good flexibility at the usage time as it let you index whatever property of type string of whatever business entity. All of this is without being intrusive in our model.  &lt;p&gt;Now that we know about the architecture of our Framework it is time to look deeper in the details of the implementation.&lt;/p&gt; &lt;p&gt;&lt;em&gt;This post is cross-posted on &lt;a href="http://blog.innoveo.com/archive.aspx/2008/3/7/indexing-and-searching-business-entities-using-lucene-net-framework-part-3"&gt;innoveo blog&lt;/a&gt; &lt;/em&gt;&lt;em&gt;and in French on my .NET community portal &lt;/em&gt;&lt;a href="http://www.techheadbrothers.com/Articles.aspx/indexer-rechercher-entites-metier-aide-framework-lucene-net"&gt;&lt;em&gt;Tech Head Brothers&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5932595" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/lkempe/archive/tags/Tools/default.aspx">Tools</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/innoveo+solutions/default.aspx">innoveo solutions</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Generics/default.aspx">Generics</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Reflection/default.aspx">Reflection</category></item><item><title>Indexing and searching business entities using Lucene.Net Framework, part 2</title><link>http://weblogs.asp.net/lkempe/archive/2008/03/07/indexing-and-searching-business-entities-using-lucene-net-framework-part-2.aspx</link><pubDate>Fri, 07 Mar 2008 09:16:32 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5932068</guid><dc:creator>lkempe</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/lkempe/rsscomments.aspx?PostID=5932068</wfw:commentRss><comments>http://weblogs.asp.net/lkempe/archive/2008/03/07/indexing-and-searching-business-entities-using-lucene-net-framework-part-2.aspx#comments</comments><description>&lt;p&gt;&lt;em&gt;&lt;img src="http://farm3.static.flickr.com/2032/2105387404_33d2e9ed92_o.gif"&gt; &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Conception using generics and reflection of a search engine to index and search content in your business entities without being intrusive.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Part 1 is available following this link &lt;a href="http://weblogs.asp.net/lkempe/archive/2007/11/16/indexing-and-searching-business-entities-using-lucene-net-framework-part-1.aspx" target="_blank"&gt;Indexing and searching business entities using Lucene.Net Framework, part 1&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;Lucene.Net presentation&lt;/h3&gt; &lt;p&gt;&lt;a href="http://incubator.apache.org/lucene.net/" target="_blank"&gt;Lucene.Net&lt;/a&gt; is an open source project coming from the Java world currently incubating at the Apache Software Foundation (ASF). It is a source code port on the .NET platform using C#, done class-by-class, API-per-API, of the indexing and searching engine algorithms of Java &lt;a href="http://lucene.apache.org/java/docs/index.html" target="_blank"&gt;Lucene&lt;/a&gt;.  &lt;p&gt;Apache Lucene is an efficient indexing and searching engine for text data. However it is not offering integrated support for document like &lt;a href="http://wiki.apache.org/lucene-java/LuceneFAQ#head-37523379241b88fd90bcd1de81b74e7ec8843f72" target="_blank"&gt;Office Word&lt;/a&gt; or &lt;a href="http://wiki.apache.org/lucene-java/LuceneFAQ#head-c45f8b25d786f4e384936fa93ce1137a23b7e422" target="_blank"&gt;PDF&lt;/a&gt;, you need to use extensions able to extract the text content of a document in order to be able index it. This is also mandatory for markup documents like &lt;a href="http://wiki.apache.org/lucene-java/LuceneFAQ#head-e7d23f91df094d7baeceb46b04d518dc426d7d2e" target="_blank"&gt;HTML&lt;/a&gt;.  &lt;p&gt;Lucene.Net follows scrupulously the APIs defined in the classes of the original Lucene Java version. The API names as well as the class names are preserved with the intention to follow naming guidelines of the C# language. For example, the method &lt;em&gt;Hits.length()&lt;/em&gt; of the Java implementation is written &lt;em&gt;Hits.Length()&lt;/em&gt; in its C# version.  &lt;p&gt;Like the port of the APIs and the classes in C#, the algorithm of the Java version of Lucene is also ported in the C# version. This means that an index created using the Java version of Lucene is 100% compatible with it C# version, in reading, writing and updating. Therefore two processes, one written in Java and the other in C#, could achieve concurrent searches using the same index.  &lt;p&gt;You might consult the documentation of the last stable version, version 2.0, &lt;a href="http://incubator.apache.org/lucene.net/docs/2.0/Lucene.Net/" target="_blank"&gt;on the following page&lt;/a&gt;. To download the last stable version &lt;a href="http://incubator.apache.org/lucene.net/download/" target="_blank"&gt;browse to this page&lt;/a&gt;. To get more information about Lucene I recommend using the &lt;a href="http://lucene.apache.org/java/docs/index.html" target="_blank"&gt;pages dedicated to the Java version of Lucene&lt;/a&gt; which are much more consistent.  &lt;h4&gt;Lucene.Net Architecture&lt;/h4&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt; &lt;center&gt;&lt;img alt="Lucene.Net Architecture" src="http://farm3.static.flickr.com/2412/2316420682_b2fe668382_o.jpg"&gt;&lt;/center&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;The lower layer is the data access layer (Storage). Then, the upper layer is about accessing the index files (data access). This layer is used by the indexing system and the searching system. On top of those we find a layer for searching and a search request parser layer used by the searching part of Lucene.Net. Identically we found a parser layer and a document layer used for the indexation part of Lucene.Net. &lt;/p&gt; &lt;p&gt; &lt;p&gt;To get more information about Lucene I recommend reading the presentation on &lt;a href="http://lucene.apache.org/java/docs/features.html" target="_blank"&gt;Lucene website&lt;/a&gt;.  &lt;p&gt;Now that we got a better view on what is Lucene.Net about we will see in the next part how we will use it to index the properties of our business entities.  &lt;p&gt;&lt;em&gt;This post is cross-posted on &lt;a href="http://blog.innoveo.com/archive.aspx/2008/3/7/indexing-and-searching-business-entities-using-lucene-net-framework-part-2"&gt;innoveo blog&lt;/a&gt; &lt;/em&gt;&lt;em&gt;and in French on my .NET community portal &lt;/em&gt;&lt;a href="http://www.techheadbrothers.com/Articles.aspx/indexer-rechercher-entites-metier-aide-framework-lucene-net"&gt;&lt;em&gt;Tech Head Brothers&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5932068" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/lkempe/archive/tags/Tools/default.aspx">Tools</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/innoveo+solutions/default.aspx">innoveo solutions</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Generics/default.aspx">Generics</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Reflection/default.aspx">Reflection</category></item><item><title>Indexing and searching business entities using Lucene.Net Framework, part 1</title><link>http://weblogs.asp.net/lkempe/archive/2007/11/16/indexing-and-searching-business-entities-using-lucene-net-framework-part-1.aspx</link><pubDate>Fri, 16 Nov 2007 08:59:02 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5246525</guid><dc:creator>lkempe</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/lkempe/rsscomments.aspx?PostID=5246525</wfw:commentRss><comments>http://weblogs.asp.net/lkempe/archive/2007/11/16/indexing-and-searching-business-entities-using-lucene-net-framework-part-1.aspx#comments</comments><description>&lt;p&gt;&lt;em&gt;Conception using generics and reflection of a search engine to index and search content in your business entities without being intrusive.&lt;/em&gt;  &lt;h3&gt;&lt;a name="1.section"&gt;Introduction&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Today, one of the functionality that almost all web sites implements is a method to index content and give it users the possibility to search that content spread into its web pages. It is one of the simplest ways to improve the user experience on your web site.  &lt;p&gt;Blogs brought categories/tags giving the possibility to label the information. However this advantageous method isn’t always sufficient. It is advisable to then use a real content indexing method.  &lt;p&gt;In this set of posts I propose to take a look at the indexing and searching method I implemented on the web site of &lt;a href="http://www.innoveo.com/"&gt;innoveo solutions&lt;/a&gt;, my new company. I hope also to bring soon this system to my web site &lt;a href="http://www.techheadbrothers.com/"&gt;Tech Head Brothers&lt;/a&gt;.  &lt;p&gt;Both web sites, innoveo solutions and Tech Head Brothers, were developed using &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=236"&gt;Domain Driven Design&lt;/a&gt;. So, we started by defining a domain model with our business entities. In this layer we do not concentrate on technical aspects for example like persistence. On the other hand we do concentrate on the domain we want to address.  &lt;p&gt;One of the main ideas is to avoid being intrusive in the domain model with any inheritance of technical classes or to link this layer with any technical frameworks.  &lt;p&gt;To achieve this goal we will use an &lt;a href="http://euss.evaluant.com/"&gt;O/R mapping tool (Euss)&lt;/a&gt; for the business entities persistence as well as the &lt;a href="http://incubator.apache.org/lucene.net/"&gt;Lucene.Net framework&lt;/a&gt; for the indexing part.  &lt;p&gt;Following quite some discussions (Thanks &lt;a href="http://www.didierbeck.com/"&gt;Didier&lt;/a&gt; ;) in which we asked us if we would better use a service offered by one of the searching big players on the Internet, we finally decided to keep the control of our searching tool.  &lt;p&gt;Wanting to be independent of any database and services like Full-Text indexing, or from services like Indexing Services, we decided to use Lucene.Net to avoid having to re-implement everything from scratch.  &lt;p&gt;In the following posts, I will present an introduction of Lucene.Net; we will see the architecture I have chosen for the indexing and searching framework; the implementation details of that framework and finally an example of integration into a data access layer.&lt;/p&gt; &lt;p&gt;&lt;em&gt;This post is cross-posted on &lt;a href="http://blog.innoveo.com/archive.aspx/2007/12/12/indexing-and-searching-business-entities-using-lucene-net-framework-part-1" target="_blank"&gt;innoveo blog&lt;/a&gt; &lt;/em&gt;&lt;em&gt;and in French on my .NET community portal &lt;/em&gt;&lt;a href="http://www.techheadbrothers.com/Articles.aspx/indexer-rechercher-entites-metier-aide-framework-lucene-net"&gt;&lt;em&gt;Tech Head Brothers&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5246525" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/lkempe/archive/tags/Tools/default.aspx">Tools</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/innoveo+solutions/default.aspx">innoveo solutions</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Generics/default.aspx">Generics</category><category domain="http://weblogs.asp.net/lkempe/archive/tags/Reflection/default.aspx">Reflection</category></item></channel></rss>