<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kamil Kliczbor @ asptip.net</title>
	<atom:link href="http://asptip.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://asptip.net</link>
	<description></description>
	<lastBuildDate>Fri, 24 Apr 2015 13:52:14 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Castle Windsor – IContributeComponentModelConstruction</title>
		<link>http://asptip.net/2013/12/17/castle-windsor-icontributecomponentmodelconstruction/</link>
		<comments>http://asptip.net/2013/12/17/castle-windsor-icontributecomponentmodelconstruction/#comments</comments>
		<pubDate>Tue, 17 Dec 2013 22:20:37 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[Castle Windsor]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=431</guid>
		<description><![CDATA[Wprowadzenie Szczerze powiedziawszy, ciężko jest określić polską nazwę dla interfejsu IContributeComponentModelConstruction. Powiedzmy, że na potrzebę tego wpisu będę się posługiwać sformułowaniem inspektor. A w samym wpisie opiszę czym jest i jak używać inspektorów. Inspektor Klasa implementująca interfejs IContributeComponentModelConstruction ma wgląd w metadane komponentów. Taki inspektor według dedykowanej logiki może zmienić konfigurację zarejestrowanego serwisu. Sam Castle posiada [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Wprowadzenie</h2>
<p>Szczerze powiedziawszy, ciężko jest określić polską nazwę dla interfejsu <em>IContributeComponentModelConstruction</em>. Powiedzmy, że na potrzebę tego wpisu będę się posługiwać sformułowaniem inspektor. A w samym wpisie opiszę czym jest i jak używać inspektorów.</p>
<p><span id="more-431"></span></p>
<h2>Inspektor</h2>
<p>Klasa implementująca interfejs <em>IContributeComponentModelConstruction</em> ma wgląd w metadane komponentów. Taki inspektor według dedykowanej logiki może zmienić konfigurację zarejestrowanego serwisu. Sam Castle posiada kilka wbudowanych inspektorów, które związane są m.in. z proxy, zależnościami, czy zarządzaniem trybem życia komponentów. Implementacje tego interfejsu uruchamiane są zaraz po zebraniu metadanych odnośnie zarejestrowanego komponentu.</p>
<blockquote><p>Nie zaleca się modyfikowania wartości metadanych instancji ComponentModel poza inspektorami.</p></blockquote>
<p>Definicja interfejsu jest następująca:</p>
<pre class="brush: csharp; gutter: true; first-line: 1">namespace Castle.MicroKernel.ModelBuilder
{
  /// &lt;summary&gt;
  /// Implementors must inspect the component for a given information or parameter.
  /// 
  /// &lt;/summary&gt;
  public interface IContributeComponentModelConstruction
  {
    /// &lt;summary&gt;
    /// Usually the implementation will look in the configuration property
    ///               of the model or the service interface, or the implementation looking for
    ///               something.
    /// &lt;/summary&gt;
    /// &lt;param name="kernel"&gt;The kernel instance&lt;/param&gt;&lt;param name="model"&gt;The component model&lt;/param&gt;
    void ProcessModel(IKernel kernel, ComponentModel model);
  }
}</pre>
<p>Widzimy, że interfejs eksponuje jedną metodę, która przyjmuje parametry o typach IKernel oraz ComponentModel.</p>
<p>Podpięcie dedykowanego inspektora polega na dodaniu własnej implementacji do kolekcji inspektorów:</p>
<pre class="brush: csharp; gutter: true; first-line: 1">container.Kernel.ComponentModelBuilder.AddContributor(new MyContributor());</pre>
<h2>Przykład</h2>
<p>Troszkę ciężko jest wymyślić jakiś sensowny przykład bez kontekstu, który będzie ładnie potrafił ukazać działanie przykładowego inspektora.<br />
Widok na solution:</p>
<p><a href="http://asptip.net/wp-content/uploads/2013/12/WindsorContributors.png"><img class="alignnone size-full wp-image-437" alt="WindsorContributors" src="http://asptip.net/wp-content/uploads/2013/12/WindsorContributors.png" width="268" height="205" /></a></p>
<p>Powiedzmy, że będziemy chcieli umieć zmienić tryb życia komponentu w zależności czy zostanie on oznaczony specjalnym atrybutem. Nazwijmy ten atrybut <em>TransientAttribute</em>. Jego definicja jest prosta, a sam atrybut służy jedynie jako "marker" do oznaczania klas:</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using System;
namespace WindsorContributors
{
    public class TransientAttribute : Attribute
    {
    }
}</pre>
<p>Zdefiniujmy dwa serwisy,  które będą użyte w tym projekcie. Jeden z nich będzie miał cykl życia Singleton, natomiast cykl durugiego ulegnie zmianie przez wpięcie naszego kontrybutora. Jak widać w drugim przypadku <em>SingletonChangedService</em> jest oznaczony atrybutem <em>Transient</em>.</p>
<pre class="brush: csharp; gutter: true; first-line: 1">namespace WindsorContributors
{
    public class SingletonService
    {
    }

    [Transient]
    public class SingletonChangedService
    {
    }
}</pre>
<p>Definicja Instalatora zależności zakłada rejestrację komponentów z trybem życia Singleton (domyślnie Windsor Castle ustawia taki tryb, jeżeli nie został on explicite wskazany):</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace WindsorContributors
{
    public class WindsorInstaller : IWindsorInstaller{
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Component.For&lt;SingletonService&gt;(),
                Component.For&lt;SingletonChangedService&gt;()
                );
        }
    }
}</pre>
<p>No i wreszcie samo mięsko: inspektor sprawdza tryb życia i istnienie atrybutu <em>Transient</em>. Jeżeli te warunki są spełnione, to komponent otrzymuje tryb życia Transient.</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ModelBuilder;

namespace WindsorContributors
{
    public class TransientAttributeInspector : IContributeComponentModelConstruction
    {
        public void ProcessModel(IKernel kernel, ComponentModel model)
        {
            if (model.LifestyleType != LifestyleType.Transient)
            {
                var hasAttribute = model.Implementation.GetCustomAttributes(typeof (TransientAttribute), false).Length &gt; 0;
                if (hasAttribute)
                {
                    model.LifestyleType = LifestyleType.Transient;
                }
            }            
        }
    }
}</pre>
<p>Główne wejście programu. Zwróćmy uwagę na kolejność w jakiej rejestrujemy inspektor oraz wskazujemy na instalator zależności.</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using System;
using Castle.Windsor;

namespace WindsorContributors
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var container = new WindsorContainer())
            {
                container.Kernel.ComponentModelBuilder.AddContributor(new TransientAttributeInspector());
                container.Install(new WindsorInstaller());
                var singleton1 = container.Resolve&lt;SingletonService&gt;();
                var singleton2 = container.Resolve&lt;SingletonService&gt;();
                var transient1 = container.Resolve&lt;SingletonChangedService&gt;();
                var transient2 = container.Resolve&lt;SingletonChangedService&gt;();

                Console.WriteLine("Wartości singleton1 i singleton2 są równe: {0}", singleton1.Equals(singleton2));
                Console.WriteLine("Wartości transient1 i transient2 są równe: {0}", transient1.Equals(transient2));
                Console.ReadKey();
            }
        }
    }
}</pre>
<p>W rezultacie otrzymujemy następujący output z konsoli. Można by rzec w ujęciu matematycznym CND.</p>
<pre class="brush: shell; gutter: true; first-line: 1">Wartości singleton1 i singleton2 są równe: True
Wartości transient1 i transient2 są równe: False</pre>
<h2>Podsumowanie</h2>
<p>Jednym z głównych i ciekawych spostrzeżeń jest to, że należy w pierwszej kolejności wskazać inspektory, a następnie zainstalować komponenty. W przeciwnym razie, nasz inspektor nie zostanie wywołany, a oczekiwany rezultat nie będzie otrzymany.</p>
<p>Innym spostrzeżeniem jest to, że inspektory mają dostęp do metadanych zarejestrowanych komponentów. W inspektorze nie mamy dostępu do instancji, ale tylko metadanych rejestrowanych komponentów.</p>
<h2>Bibliografia</h2>
<p>Głównie ze strony Castla: <a href="http://docs.castleproject.org/Windsor.ComponentModel-construction-contributors.ashx">http://docs.castleproject.org/Windsor.ComponentModel-construction-contributors.ashx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/12/17/castle-windsor-icontributecomponentmodelconstruction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Castle Windsor &#8211; cykl życia komponentów</title>
		<link>http://asptip.net/2013/12/10/castle-windsor-cykl-zycia-komponentow/</link>
		<comments>http://asptip.net/2013/12/10/castle-windsor-cykl-zycia-komponentow/#comments</comments>
		<pubDate>Tue, 10 Dec 2013 22:51:56 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[Castle Windsor]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=418</guid>
		<description><![CDATA[Wprowadzenie Komponenty tworzone przez kontener posiadają swój cykl życia. Cykl życia określa warunki w jakich są tworzone, używane oraz niszczone. W Castle można skonfigurować mechanizmy, które w sposób dedykowany  będą umiały zarządzać dodatkową logiką przy powoływaniu oraz niszczeniu wcześniej utworzonych instancji. Wpis ten nie będzie omawiał dedykowanych zarządców powoływania i odwoływania instancji. Powoływanie W kontenerze w [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Wprowadzenie</h2>
<p>Komponenty tworzone przez kontener posiadają swój cykl życia. Cykl życia określa warunki w jakich są tworzone, używane oraz niszczone. W Castle można skonfigurować mechanizmy, które w sposób dedykowany  będą umiały zarządzać dodatkową logiką przy powoływaniu oraz niszczeniu wcześniej utworzonych instancji. Wpis ten nie będzie omawiał dedykowanych zarządców powoływania i odwoływania instancji.</p>
<p><span id="more-418"></span></p>
<h2>Powoływanie</h2>
<p>W kontenerze w odniesieniu do tworzenia obiektów użyte jest sformułowanie"<em>commission concerns</em>". Metody powoływujące są uruchamiane na rzecz wcześniej już zinstancjonowanych komponentów, dla których zostały wstrzyknięte wszystkie zależności. Konfigurując więc conmmision concerny musimy mięć na uwadze, że otrzymujemy gotową do użycia instancję. Castle w trójnasób wspiera powoływanie obiektów poprzez wywołanie metody <em>OnCreate</em> w rejestratorze, implementację interfejsu <em>IInitializable</em> lub <em>ISupportInitialize</em>.</p>
<h3>OnCreate</h3>
<p>Jest to metoda, której można użyć na konfiguratorze rejestracji, jeżeli chcemy skonfigurować inline przetwarzanie instancji zaraz po jej inicjalizacji. Poniżej został przedstawiony listing użycia API na podstawie przykładu ze strony Castla:</p>
<pre class="brush: csharp;">container.Register(
   Component.For&lt;IService&gt;()
      .ImplementedBy&lt;MyService&gt;()
      .OnCreate((kernel, instance) =&gt; instance.Timestamp = DateTime.UtcNow)
   );</pre>
<h3>IInitializable</h3>
<p>Interfejs ten jest ulokowany w przestrzeni nazw <em>Castle.Core</em>. Castle traktuje w sposób szczególny klasy implementujące ten interfejs - jest on uruchamiany po podstawowej inicjalizacji instancji. Jedynym minusem użycia tego interfejsu jest to, że nie można przekazać żadnych zależności z zewnątrz do takiej instancji.</p>
<pre class="brush: csharp;">void Initialize();</pre>
<h3>ISupportInitalization</h3>
<p>W przypadku, jeżeli nie chcemy mieć bezpośredniego odwołania do Castle w domenie,  można posłużyć się niezależnym interfejsem <em>ISupportInitalization</em> z przestrzeni nazw <em>System.ComponentModel</em>. Interfejs tak samo jak w powyższym przypadku ma ograniczenie odnośnie uzyskiwania dodatkowych zależności od kontenera. Metody <em>BeginInit</em> oraz <em>EndInit</em> wywoływane są bezpośrednio po sobie, więc nie ma znaczenia w której z nich umieścimy logikę inicjalizacyjną.</p>
<pre class="brush: csharp;">void BeginInit();
void EndInit();</pre>
<h2>Odwoływanie</h2>
<p>Udział w odwoływaniu obiektów (<em>decomission</em>) można zrealizować na dwa sposoby: wywołanie metody <em>OnDestroy</em> w rejestratorze lub implementację interfejsu <em>IDisposable</em>. Castle trzyma odniesienia do każdej encji, którą stworzył. Ważne jest, aby pamiętać o odpowiednim zarządzaniu pamięcią i zwalnianiu zasobów, kiedy nie są już używane.</p>
<h3>OnDestroy</h3>
<p>Jest to metoda analogiczna w stosunku do OnCreate, przy czym w tym przypadku nie mamy "w ręku" implementacji IKernel. Poniżej został przedstawiony listing użycia API na podstawie przykładu ze strony Castla:</p>
<pre class="brush: csharp; gutter: true; first-line: 1">container.Register(Component.For&lt;MyClass&gt;()
   .LifestyleTransient()
   .OnDestroy(myInstance =&gt; myInstance.ByeBye())
);</pre>
<h3>IDisposable</h3>
<p>W tym przypadku kontener jest w stanie obsłużyć standardowy interfejs <em>IDisposable</em> używany przez .NET przy niszczeniu obiektów. Jeżeli dana instancja będzie miała być zniszczona, to zostanie wywołana metoda <em>Dispose</em>.</p>
<h2>Przykład - eksperyment</h2>
<p>W przykładzie pokażę sposób użycia wyżej wymienionych implementacji. Będziemy mieli następujące komponenty: <em>IService</em> wraz z implementacją <em>MyService</em> oraz <em>DateTimeProvider</em> wstrzykiwany do tej implementacji .</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using System;
using System.ComponentModel;
using Castle.Core;

namespace CommissionConcerns
{
    public interface IService
    {
    }

    public class MyService : IService, ISupportInitialize, IInitializable, IDisposable
    {
        private readonly DateTimeProvider _dateTimeProvider;

        public MyService(DateTimeProvider dateTimeProvider)
        {
            _dateTimeProvider = dateTimeProvider;
            Console.WriteLine("MyService.ctor {0}", _dateTimeProvider.GetCurrentDateTime());
        }

        public void BeginInit()
        {
            Console.WriteLine("BeginInit()");
        }

        public void EndInit()
        {
            Console.WriteLine("EndInit()");
        }

        public void Initialize()
        {
            Console.WriteLine("Initialize()");
        }

        public void Dispose()
        {
            Console.WriteLine("Dispose()");
        }
    }

    public class DateTimeProvider
    {
        public DateTime GetCurrentDateTime()
        {
            return DateTime.Now;
        }
    }
}</pre>
<p>Rejestracje oraz konfiguracja powoływania oraz odwoływania instancji:</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using System;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace CommissionConcerns
{
    internal class WindsorInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Component
                    .For&lt;IService&gt;()
                    .ImplementedBy&lt;MyService&gt;()
                    .OnCreate(
                        (kernel, instance) =&gt; Console.WriteLine("OnCreate: instance is null = {0}",  instance == null))
                    .OnDestroy(
                        (kernel, instance) =&gt; Console.WriteLine("OnDestroy: instance is null = {0}",  instance == null)),
                Component
                    .For&lt;DateTimeProvider&gt;()
                );
        }
    }
}</pre>
<p>Oraz widok na listing z metody Main:</p>
<pre class="brush: csharp; gutter: true; first-line: 1">using System;
using Castle.Windsor;

namespace CommissionConcerns
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            using (var container = new WindsorContainer())
            {
                container.Install(new WindsorInstaller());
                var service = container.Resolve&lt;IService&gt;();
                Console.WriteLine("After object comission");
            }

            Console.WriteLine("After object decomission");
            Console.ReadKey();
        }
    }
}</pre>
<p>Rezultat wykonania przykładu:</p>
<pre class="brush: powershell; gutter: true; first-line: 1">MyService.ctor 12/10/2013 20:37:53 AM
OnCreate: instance is null = False
Initialize()
BeginInit()
EndInit()
After object comission
OnDestroy: instance is null = False
Dispose()
After object decomission</pre>
<h2>Wnioski</h2>
<p>Windsor Castle dostarcza kilka miejsc rozszerzeń, dzięki którym można kontrolować proces inicjalizacji oraz niszczenia instancji. Co więcej, konfiguracja umożliwia zdefiniowanie logiki inicjalizacji wprost przy rejestracji komponentu lub poprzez implementację interfejsu z przestrzeni nazw Castle lub systemowych. Przy czym przy drugim podejściu nie musimy skazywać np. projektu domeny na bezpośrednią referencję do kontenera. Innym wnioskiem jest to, że poszczególne podejścia zajmują swoje ustalone miejsce w kolejności wywoływania.</p>
<h2>Bibliografia</h2>
<p>Głównie <a href="http://docs.castleproject.org/Windsor.Lifecycle.ashx">http://docs.castleproject.org/Windsor.Lifecycle.ashx</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/12/10/castle-windsor-cykl-zycia-komponentow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Castle Windsor &#8211; tryb życia komponentów w przykładzie</title>
		<link>http://asptip.net/2013/12/05/windsor-castle-tryb-zycia-komponentow-w-przykladzie/</link>
		<comments>http://asptip.net/2013/12/05/windsor-castle-tryb-zycia-komponentow-w-przykladzie/#comments</comments>
		<pubDate>Thu, 05 Dec 2013 21:58:49 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Castle Windsor]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=388</guid>
		<description><![CDATA[Wprowadzenie Wpis nawiązuje do poprzedniego, teoretycznego wprowadzenia do trybów życia w Windsor Castle. W tym przykładzie spróbujemy posłużyć się semi-biznesowym przypadkiem. Powiedzmy, że mamy system do składania zamówień, który na podstawie kodu produktu oraz pewnej konfiguracji, będzie potrafił udzielić zniżki na wybrany produkt. Zepniemy te bardzo "wybujałe" wymagania i dostarczymy projekt w technologii ASP.NET MVC. [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Wprowadzenie</h2>
<p>Wpis nawiązuje do poprzedniego, <a title="Windsor Castle – tryb życia komponentów" href="http://asptip.net/2013/11/28/windsor-castle-tryb-zycia-komponentow/">teoretycznego wprowadzenia do trybów życia w Windsor Castle</a>. W tym przykładzie spróbujemy posłużyć się semi-biznesowym przypadkiem. Powiedzmy, że mamy system do składania zamówień, który na podstawie kodu produktu oraz pewnej konfiguracji, będzie potrafił udzielić zniżki na wybrany produkt. Zepniemy te bardzo "wybujałe" wymagania i dostarczymy projekt w technologii ASP.NET MVC.</p>
<p><span id="more-388"></span></p>
<h2>Modele, kontrolery, widoki i walidatory</h2>
<p>Poniżej przedstawiłem screen z widokiem na solution tego projektu. W dalszych akapitach krótko scharakteryzuje standardowe byty jak dla aplikacji ASP.NET MVC , a później przedstawię koncepcję podpięcia Windsora do tego projektu.</p>
<p><a href="http://asptip.net/wp-content/uploads/2013/11/WindsorLifeStyles.png"><img class="alignnone size-full wp-image-392" alt="WindsorLifeStyles" src="http://asptip.net/wp-content/uploads/2013/11/WindsorLifeStyles.png" width="313" height="592" /></a></p>
<p>Poniżej znajduje się listing do <em>Product.cs</em>. Niczego specjalnego tutaj nie mamy. Ot taka zwykła encja, mamy kod produktu, liczbę zamówionych egzemplarzy oraz informację o tym, czy zostanie udzielona zniżka.</p>
<pre class="brush:csharp">namespace WindsorLifeStyles.Models
{
    public class Product
    {
        public int Id { get; set; }

        public string Code { get; set; }

        public int Quantity { get; set; }

        public bool Discount { get; set; }
    }
}</pre>
<p>Kontroler <em>ProductsController.cs</em> steruje logiką zarządzania przydzielania zniżki użytkownikowi, który zamierza kupić dany produkt. Jako zależności do kontrolera produktów, wstrzykiwane są dwa komponenty - <em>ProductDiscountCache</em> oraz <em>CurrentUserProvider</em>. Do ViewBaga widoku doklejamy informacje o liczbie wywołań poszczególnych komponentów - kontrolera, providera id użytkownika oraz cache zniżek produktów.</p>
<pre class="brush:csharp">using System.Web.Mvc;
using WindsorLifeStyles.Models;
using WindsorLifeStyles.Services;

namespace WindsorLifeStyles.Controllers
{
    public class ProductsController : Controller
    {
        private readonly ProductDiscountCache _productDiscountCache;
        private readonly CurrentUserProvider _currentUserProvider;
        private int _calls;
        public ProductsController(
            ProductDiscountCache productDiscountCache,
            CurrentUserProvider currentUserProvider)
        {
            _productDiscountCache = productDiscountCache;
            _currentUserProvider = currentUserProvider;
        }

        public ActionResult Index()
        {
            _calls++;
            SetCallsData();
            return View(new Product());
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(Product product)
        {
            _calls++;

            if (ModelState.IsValid)
            {
                var currentUserId = _currentUserProvider.GetCurrentUserId();
                product.Discount = _productDiscountCache.HasDiscount(product.Code, currentUserId);

                SetCallsData();
                return View("Details", product);
            }

            SetCallsData();
            return View(product);
        }

        private void SetCallsData()
        {
            ViewBag.GetCurrentUserCalls = _currentUserProvider.GetCalls;
            ViewBag.HasDiscountCalls = _productDiscountCache.GetCalls;
            ViewBag.ControllerCalls = _calls;
        }
    }
}</pre>
<p>Widok <em>Details.cshtml</em> wyświetla podsumowanie zamówienia produktu oraz liczbę wywołań poszczególnych komponentów<em>.</em></p>
<pre class="brush:csharp">@model WindsorLifeStyles.Models.Product

@{
    ViewBag.Title = "Details";
}

&lt;h2&gt;Details&lt;/h2&gt;

&lt;fieldset&gt;
    &lt;legend&gt;Product&lt;/legend&gt;

    &lt;div class="display-label"&gt;
        @Html.DisplayNameFor(model =&gt; model.Code)
    &lt;/div&gt;
    &lt;div class="display-field"&gt;
        @Html.DisplayFor(model =&gt; model.Code)
    &lt;/div&gt;

    &lt;div class="display-label"&gt;
        @Html.DisplayNameFor(model =&gt; model.Quantity)
    &lt;/div&gt;
    &lt;div class="display-field"&gt;
        @Html.DisplayFor(model =&gt; model.Quantity)
    &lt;/div&gt;

    &lt;div class="display-label"&gt;
        @Html.DisplayNameFor(model =&gt; model.Discount)
    &lt;/div&gt;
    &lt;div class="display-field"&gt;
        @Html.DisplayFor(model =&gt; model.Discount)
    &lt;/div&gt;
    &lt;div class="display-field"&gt;
        ControllerCalls:  @ViewBag.ControllerCalls
    &lt;/div&gt;
    &lt;div class="display-field"&gt;
        GetCurrentUserCalls:  @ViewBag.GetCurrentUserCalls
    &lt;/div&gt;
    &lt;div class="display-field"&gt;
        HasDiscountCalls:  @ViewBag.HasDiscountCalls
    &lt;/div&gt;       
&lt;/fieldset&gt;</pre>
<p>Z kolei widok <em>Index.cshtml</em> prezentuje formularz dodawania produktu.</p>
<pre class="brush:csharp">@model WindsorLifeStyles.Models.Product

@{
    ViewBag.Title = "Create";
}

&lt;h2&gt;Create&lt;/h2&gt;

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    &lt;fieldset&gt;
        &lt;legend&gt;Product&lt;/legend&gt;

        &lt;div class="editor-label"&gt;
            @Html.LabelFor(model =&gt; model.Code)
        &lt;/div&gt;
        &lt;div class="editor-field"&gt;
            @Html.EditorFor(model =&gt; model.Code)
            @Html.ValidationMessageFor(model =&gt; model.Code)
        &lt;/div&gt;

        &lt;div class="editor-label"&gt;
            @Html.LabelFor(model =&gt; model.Quantity)
        &lt;/div&gt;
        &lt;div class="editor-field"&gt;
            @Html.EditorFor(model =&gt; model.Quantity)
            @Html.ValidationMessageFor(model =&gt; model.Quantity)
        &lt;/div&gt;

        &lt;p&gt;
            &lt;input type="submit" value="Create" /&gt;
        &lt;/p&gt;
        &lt;div class="display-field"&gt;
            ControllerCalls:  @ViewBag.ControllerCalls
        &lt;/div&gt;
        &lt;div class="display-field"&gt;
            GetCurrentUserCalls:  @ViewBag.GetCurrentUserCalls
        &lt;/div&gt;
        &lt;div class="display-field"&gt;
            HasDiscountCalls:  @ViewBag.HasDiscountCalls
        &lt;/div&gt;
    &lt;/fieldset&gt;
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}</pre>
<p>Komponent <em>CurrentUserProvider</em> dostarcza informacji o identyfikatorze zalogowanego użytkownika. W tym przypadku zawsze tym identyfikatorem jest liczba 1, ale w prawdziwej implementacji provider ten powinien odwoływać się do mechanizmu uwierzytelniającego. W odniesieniu do stylu życia, komponent ten skonfigurujemy jako PerWebRequest, gdyż identyfikator zalogowanego użytkownika w ramach jednego requesta się nie zmienia. Co więcej jest to pewnego rodzaju optymalizacja, gdyż wywołanie tego providera może odbyć się wielokrotnie przy jednym requeście.</p>
<pre class="brush:csharp">namespace WindsorLifeStyles.Services
{
    public class CurrentUserProvider
    {
        private int _calls;

        public int GetCalls
        {
            get { return _calls; }
        }

        public long GetCurrentUserId()
        {
            _calls++;
            return 1;
        }
    }
}</pre>
<p><em>ProductDiscountCache</em> jest komponentem, który dostarcza cache zmieniający się niezwykle rzadko lub wcale. Dobrym stylem życia dla tego komponentu jest Singleton. Przeładowanie cache odbędzie się w momencie, gdy kontener zostanie podniesiony od nowa, co stanie się przy restarcie puli. Natomiast sama implementacja leniwie odczytuje dane (wzorzec Lazy Loading), które zapisuje do słownika.</p>
<pre class="brush:csharp">using System;
using System.Collections.Generic;

namespace WindsorLifeStyles.Services
{
    public class ProductDiscountCache
    {
        private readonly Lazy&lt;Dictionary&lt;string, IList&gt;&gt; _cache;

        private int _calls;

        public int GetCalls
        {
            get { return _calls; }
        }

        public ProductDiscountCache()
        {
            _cache = new Lazy&lt;Dictionary&lt;string, IList&gt;&gt;(GetCache);
        }

        private Dictionary&lt;string, IList&gt; GetCache()
        {
            return new Dictionary&lt;string, IList&gt;
                {
                    {"A", new List {1, 2, 3}},
                    {"B", new List {1}},
                    {"C", new List {2, 3}},
                };
        }

        public bool HasDiscount(string code, long currentUserId)
        {
            _calls++;

            var cache = _cache.Value;
            if (cache.ContainsKey(code))
            {
                var userIds = cache[code];
                return userIds.Contains(currentUserId);
            }

            return false;
        }
    }
}</pre>
<h2>Walidacja</h2>
<p>Istotną składową tego projektu pod kątem zrozumienia trybu życia komponentów jest walidacja produktu, która również na podstawie CurrentUserProvider oraz ProductDiscountCache jest w stanie ustalić, czy użytkownik może dostać zniżkę na określoną liczbę produktów. W następnych akapitach napiszę jak sprytnie zintegrować walidację ASP.NET MVC z WindsorCastle.</p>
<pre class="brush:csharp">using System.Collections.Generic;
using System.Web.Mvc;
using WindsorLifeStyles.Models;
using WindsorLifeStyles.Services;

namespace WindsorLifeStyles.Validators
{
    public class ValidadatorProvider : ModelValidatorProvider
    {
        private readonly CurrentUserProvider _currentUserProvider;
        private readonly ProductDiscountCache _productDiscountCache;

        public ValidadatorProvider(CurrentUserProvider currentUserProvider, ProductDiscountCache productDiscountCache)
        {
            _currentUserProvider = currentUserProvider;
            _productDiscountCache = productDiscountCache;
        }

        public override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context)
        {
            if (metadata.Model != null)
            {
                if (typeof (Product).IsAssignableFrom(metadata.ModelType))
                {
                    yield return new ProductValidator(metadata, context, _currentUserProvider, _productDiscountCache);
                }
            }
        }
    }
}</pre>
<p>W ramach tego projektu mamy tylko jeden walidator - <em>ProductValidator</em>, który sprawdza czy użytkownik przypadkiem nie zamierza kupić więcej niż 3 produktów ze zniżką. Jeżeli ten warunek nie będzie spełniony, walidacja się nie powiedzie, a kupujący otrzyma komunikat o błędzie.</p>
<pre class="brush:csharp">using System.Collections.Generic;
using System.Web.Mvc;
using WindsorLifeStyles.Models;
using WindsorLifeStyles.Services;

namespace WindsorLifeStyles.Validators
{
    public class ProductValidator : ModelValidator
    {
        private readonly CurrentUserProvider _currentUserProvider;
        private readonly ProductDiscountCache _productDiscountCache;

        public ProductValidator(
            ModelMetadata metadata,
            ControllerContext controllerContext,
            CurrentUserProvider currentUserProvider,
            ProductDiscountCache productDiscountCache)
            : base(metadata, controllerContext)
        {
            _currentUserProvider = currentUserProvider;
            _productDiscountCache = productDiscountCache;
        }

        public override IEnumerable Validate(object container)
        {
            var product = (Product) Metadata.Model;
            var currentUserId = _currentUserProvider.GetCurrentUserId();
            var hasDiscount = _productDiscountCache.HasDiscount(product.Code, currentUserId);
            if (hasDiscount &amp;&amp; product.Quantity &gt; 3)
            {
                yield return new ModelValidationResult
                    {
                        MemberName = "Quantity",
                        Message = "Użytownik, który otrzyma zniżkę, nie może zakupić więcej niż 3 produkty."
                    };
            }
        }
    }
}</pre>
<p>I teraz chyba najważniejsza rzecz: utworzenie dedykowanego providera (<em>RootModelValidatorProvider.cs</em>), który potrafi każdorazowo wyciągnąć z kontenera listę walidatorów. Dlaczego tak ? Ano, chcemy, aby każdorazowo walidatory miały możliwość wstrzyknięcia zależności od kontenera.</p>
<pre class="brush:csharp">using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Castle.MicroKernel;

namespace WindsorLifeStyles
{
    public class RootModelValidatorProvider : ModelValidatorProvider
    {
        private readonly IKernel _kernel;

        public RootModelValidatorProvider(IKernel kernel)
        {
            _kernel = kernel;
        }

        public override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context)
        {
            var modelValidators =
                _kernel.ResolveAll()
                       .SelectMany(n =&gt; n.GetValidators(metadata, context))
                       .ToList();
            return modelValidators;
        }
    }
}</pre>
<h2>Wpięcie Windsor Castla w ASP.NET MVC</h2>
<p>Przyjrzyjmy się najpierw instalatorowi zależności(<em>WindsorInstaller.cs</em>). Wskazujemy do rejestracji:</p>
<ul>
<li>wszystkie implementację IController jako transient, czyli po prostu wszystkie kontrolery,</li>
<li>wszystkie implementacje ModelValidatorProvidera jako transient, ale bez RootModelValidatorProvidera, gdyż wkroczylibyśmy potem w nieskończoną pętlę rozwiązywania zależności</li>
<li>ProductDiscountCache jako Singleton</li>
<li>CurrentUserProvider jako PerWebRequest</li>
</ul>
<pre class="brush:csharp">using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using WindsorLifeStyles.Services;

namespace WindsorLifeStyles
{
    public class WindsorInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Classes.FromThisAssembly()
                       .BasedOn&lt;IController&gt;()
                       .LifestyleTransient(),
                Classes.FromThisAssembly()
                       .Pick()
                       .If(typeof (ModelValidatorProvider).IsAssignableFrom)
                       .If(t =&gt; t != typeof (RootModelValidatorProvider))
                       .WithServices(typeof (ModelValidatorProvider))
                       .LifestyleTransient(),
                Component.For&lt;ProductDiscountCache&gt;()
                         .LifestyleSingleton(),
                Component.For&lt;CurrentUserProvider&gt;()
                         .LifestylePerWebRequest()
                );
        }
    }
}</pre>
<p>Tworzymy własną implementację fabryki kontrolerów WindsorControllerFactory.cs opartą o Windsor Castla. Przedstawiam tutaj dosyć standardowe podejście do tematu:</p>
<pre class="brush:csharp">using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;

namespace WindsorLifeStyles
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel _kernel;

        public WindsorControllerFactory(IKernel kernel)
        {
            _kernel = kernel;
        }

        public override void ReleaseController(IController controller)
        {
            _kernel.ReleaseComponent(controller);
        }

        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
            }

            return (IController) _kernel.Resolve(controllerType);
        }
    }
}</pre>
<p>No i wreszcie spięcie wszystkiego w  Global.asax.</p>
<pre class="brush:csharp">using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Castle.Windsor;
using Castle.Windsor.Installer;

namespace WindsorLifeStyles
{
    public class MvcApplication : System.Web.HttpApplication
    {
        private static IWindsorContainer _container;

        private static void BootstrapContainer()
        {
            _container = new WindsorContainer().Install(FromAssembly.This());
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container.Kernel));
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            BootstrapContainer();

            ModelValidatorProviders.Providers.Clear();
            ModelValidatorProviders.Providers.Add(new RootModelValidatorProvider(_container.Kernel));
        }

        protected void Application_End()
        {
            _container.Dispose();
        }
    }
}</pre>
<h2>Uruchomienie aplikacji</h2>
<p>Przy pierwszym wejściu na ekran pokazuje się formularz wprowadzania danych. Zauważmy, że w tym miejscu nie jest wołana walidacja, ani też odwołania do serwisów pobierających id użytkownika i dane z cache. Dlatego otrzymujemy wartości 1, 0, 0.</p>
<h2><a href="http://asptip.net/wp-content/uploads/2013/12/IndexCreate.png"><img alt="IndexCreate" src="http://asptip.net/wp-content/uploads/2013/12/IndexCreate.png" width="316" height="385" /></a></h2>
<p>Dla danych czterech produktów o kodzie "AA" nie została udzielona zniżka. Przyjrzyjmy się liczbom wywołań poszczególnych komponentów: kontroler produktów został wywołany tylko raz, gdyż jego tryb życia to Transient. Z kolei ta sama instancja CurrentUserIdProvider została wywołana dwa razy, zgodnie z oczekiwaniami.</p>
<h2><a href="http://asptip.net/wp-content/uploads/2013/12/DetailsValidated.png"><img alt="DetailsValidated" src="http://asptip.net/wp-content/uploads/2013/12/DetailsValidated.png" width="326" height="328" /></a></h2>
<h2></h2>
<p>W ostatnim wywołaniu wprowadzamy celowo produkt, który może mieć zniżkę, ale niestety została przekroczona maksymalna liczba produktów, które można zakupić. Pojawił się komunikat walidacyjny. Zestawienie wywołań również jest zgodne z oczekiwanymi. Jedno wywołanie kontrolera (Transient), jedno wywołanie serwisu pobierającego id użytkownika oraz 3 wywołania odwołania do cache. Liczba odwołań do tego ostatniego serwisu będzie się zwiększać, co też jest potwierdzeniem stylu życia Singleton.</p>
<h2><a href="http://asptip.net/wp-content/uploads/2013/12/DetailsInvalid.png"><img alt="DetailsInvalid" src="http://asptip.net/wp-content/uploads/2013/12/DetailsInvalid.png" width="662" height="399" /></a></h2>
<h2>Podsumowanie</h2>
<p>W tym wpisie przedstawiłem sposób w jaki można skonfigurować kontener Windsor Castle w prostej aplikacji MVC. Pokazałem na przykładzie jak ustawić style życia komponentów rejestrowanych w Castle dla Transient, PerWebRequest i Singleton. Ponad to wskazałem jak powiązać kontener z mechanizmem walidacyjnym ASP.NET MVC.  Najciekawszym jednak doświadczeniem było, to , że nie musiałem rejestrować handlera do obsługi lifestyla  PerWebRequest przez wpis konfiguracyjny w web.configu (tak jak sugeruje informacja na stronie Castla).</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/12/05/windsor-castle-tryb-zycia-komponentow-w-przykladzie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Castle Windsor &#8211; tryb życia komponentów</title>
		<link>http://asptip.net/2013/11/28/windsor-castle-tryb-zycia-komponentow/</link>
		<comments>http://asptip.net/2013/11/28/windsor-castle-tryb-zycia-komponentow/#comments</comments>
		<pubDate>Thu, 28 Nov 2013 23:42:13 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[Castle Windsor]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=380</guid>
		<description><![CDATA[Wprowadzanie W tym wpisie przybliżę sposoby definiowania trybu życia komponentów w kontenerze Windsor Castle. Tryby życia W aplikacji możemy skonfigurować w ramach jakiego zakresu dany komponent ma żyć oraz kiedy ma zakończyć swój żywot. Windsor dostarcza kilka takich trybów z pudełka, a należą do nich: Singleton - czyli jedna instancja na całą aplikację, Transient - [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Wprowadzanie</h2>
<p>W tym wpisie przybliżę sposoby definiowania trybu życia komponentów w kontenerze Windsor Castle.</p>
<h2>Tryby życia</h2>
<p>W aplikacji możemy skonfigurować w ramach jakiego zakresu dany komponent ma żyć oraz kiedy ma zakończyć swój żywot. Windsor dostarcza kilka takich trybów z pudełka, a należą do nich:<br />
<span id="more-380"></span></p>
<ul>
<li>Singleton - czyli jedna instancja na całą aplikację,</li>
<li>Transient - jedna instancja na każde wywołanie z kontenera,</li>
<li>PerWebRequest - instancja jest współdzielona w ramach jednego web requesta aplikacji webowej,</li>
<li>PerThread - instancja komponentu jest współdzielona w ramach jednego wątku,</li>
<li>Pooled - zostanie stworzona pula obiektów, z której na żądanie jest pobierana jedna instancja,</li>
<li>Custom  - można utworzyć własną definicję trybu życia instancji.</li>
</ul>
<p>W 99 procentach korzysta się z pierwszych trzech, tj: Singleton, Transient oraz PerWebRequest. Pozostałych trybów życia instancji używa się sporadycznie.</p>
<blockquote><p>Jeżeli nie zostanie wskazany tryb życia , to domyślnie Windsor Castle użyje trybu Singleton.</p></blockquote>
<p>Przyjrzyjmy się zatem trybom życia z bliska, skupiając uwagę na trzech najczęściej używanych.</p>
<h3>Singleton</h3>
<p>Instancje pozyskiwane z kontenera o trybie życia Singleton są tworzone tylko raz w momencie gdy ktoś ich zażąda po raz pierwszy. Każde następne wywołanie powoduje uzyskanie tej samej instancji. Zniszczenie instancji o tybie życia Singleton nastąpi z chwilą zniszczenia instancji kontenera. Użycie metody container.Release()  nie da żadnego rezultatu. Dobrym powodem na ustawienie instacji jako Singleton jest:</p>
<ul>
<li>bezstanowość danej instancji lub</li>
<li>możliwość posiadania stanu, ale niezmiennego przez cały cykl życia aplikacji.</li>
</ul>
<p>W przypadku Singletonu należy zwrócić uwagę na pracę z komponentem w środowisku wielowątkowym.</p>
<p>Konfiguracja Singletonu w instalatorze przedstawia poniższy przykład:</p>
<pre class="brush:csharp">// domyślny Lifestyle to Singleton
Register(Component.For&lt;Car&gt;());
// lub też explicite
Register(Component.For&lt;Car&gt;().LifestyleSingleton());</pre>
<h3>Transient</h3>
<p>Instancje o cyklu życia Transient są przeciwieństwem instancji o cyklu życia Singleton. Nie są przywiązane do żadnego kontekstu, a zatem każdorazowo kiedy prosimy kontener o komponent,  otrzymujemy za każdym razem jego nową instancję.  Dobrym powodem użycia Transient jest przypadek w którym chcemy kontrolować czas życia instancji przy użyciu container.Release(). Dodatkowo, jeżeli nie jest to koniecznie, nie musimy dbać o ich bezpieczeństwo w środowisku wielowątkowym.</p>
<pre class="brush:csharp">Register(Component.For&lt;Car&gt;().LifestyleTransient());</pre>
<h3>PerWebRequest</h3>
<p>W koncepcji działania jest hybrydą pomiędzy Singletonem a Transientem. Instancja zarejestrowana w takim trybie zostanie utworzona gdy zapytamy o nią kontener po raz pierwszy w trakcie trwania web requestu. Każde kolejne prośba utworzenia kończy się zwróceniem przez kontener tej samej instancji. Próba wykonania Relase() na instancji zakończy się fiaskiem</p>
<pre class="brush:csharp">Register(Component.For&lt;Car&gt;().LifestylePerWebRequest());</pre>
<p>Według opisu na stronie Castla, ustawienie takiego trybu życia instancji wymaga konfiguracji w aplikacji webowej odpowiedniego modułu tj. <code>Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule</code>:</p>
<pre class="brush:xml">&lt;httpModules&gt;
   &lt;add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/&gt;
&lt;/httpModules&gt;</pre>
<p>Z kolei, jeżeli mamy do czynienia z IIS w wersji &gt;= 7.0, wtedy musimy umieścić konfigurację w sekcji <code>system.webServer/modules</code><code>:</code></p>
<pre class="brush:xml">&lt;configuration&gt;
   &lt;system.webServer&gt;
      &lt;modules&gt;
         &lt;add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" /&gt;
      &lt;/modules&gt;
   &lt;/system.webServer&gt;
&lt;/configuration&gt;</pre>
<h2>Przykładowa aplikacja</h2>
<p>Przykładowa aplikacja webowa napisana w ASP.NET MVC zostanie przedstawiona w kolejnym wpisie.</p>
<h2>Źródła</h2>
<p><a href="http://docs.castleproject.org/Windsor.LifeStyles.ashx">http://docs.castleproject.org/Windsor.LifeStyles.ashx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/28/windsor-castle-tryb-zycia-komponentow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Strange Visual Studio 2012 error</title>
		<link>http://asptip.net/2013/11/20/strange-visual-studio-2012-error/</link>
		<comments>http://asptip.net/2013/11/20/strange-visual-studio-2012-error/#comments</comments>
		<pubDate>Wed, 20 Nov 2013 21:01:47 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[Porady]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=375</guid>
		<description><![CDATA[When I was trying to reconnect to the Team Foundation Server  with Visual Studio 2012 I got unpredictable exception: Value was either too large or too small for a UInt32. &#160; Fortunately one of my collegues knew the answer how to fix it - just simply u need to save all documents. Nice.]]></description>
				<content:encoded><![CDATA[<p>When I was trying to reconnect to the Team Foundation Server  with Visual Studio 2012 I got unpredictable exception:</p>
<blockquote><p>Value was either too large or too small for a UInt32.</p></blockquote>
<p><a href="http://asptip.net/wp-content/uploads/2013/11/VisualStudio2012_bug_value_was_either_too_large_or_too_small_for_a_uint32.png"><img class="alignnone size-full wp-image-376" alt="VisualStudio2012_bug_value_was_either_too_large_or_too_small_for_a_uint32" src="http://asptip.net/wp-content/uploads/2013/11/VisualStudio2012_bug_value_was_either_too_large_or_too_small_for_a_uint32.png" width="387" height="185" /></a></p>
<p>&nbsp;</p>
<p>Fortunately one of my collegues knew the answer how to fix it - just simply u need to save all documents. Nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/20/strange-visual-studio-2012-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NHibernate processing *.hbm.xml order</title>
		<link>http://asptip.net/2013/11/14/nhibernate-processing-hbm-xml-order/</link>
		<comments>http://asptip.net/2013/11/14/nhibernate-processing-hbm-xml-order/#comments</comments>
		<pubDate>Thu, 14 Nov 2013 21:52:50 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate Internals]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=366</guid>
		<description><![CDATA[Recently we had small problem with defining views in our mappings. Because we use mapping export to local MS-SQL database we needed to define the views in our *.xbm.xml files. The problem was arising when we wanted to have dependencies between views. First thing we thought it would make it work was to put the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Recently we had small problem with defining views in our mappings. Because we use mapping export to local MS-SQL database we needed to define the views in our *.xbm.xml files. The problem was arising when we wanted to have dependencies between views. First thing we thought it would make it work was to put the views in the order defined by hbm's names. That did nothing. Then we started to dig in the FluentNH code and we went deeper in NH then found these interesting lines of code in the Configuration.cs:</p>
<pre class="brush:csharp">/// &lt;summary&gt;
/// Adds all of the assembly"s embedded resources whose names end with &lt;c&gt;.hbm.xml&lt;/c&gt;.
/// &lt;/summary&gt;
/// &lt;param name="assembly"&gt;The assembly.&lt;/param&gt;
/// &lt;returns&gt;This configuration object.&lt;/returns&gt;
public Configuration AddAssembly(Assembly assembly)
{
	IList resourceNames = GetAllHbmXmlResourceNames(assembly);
	if (resourceNames.Count == 0)
	{
		log.Warn("No mapped documents found in assembly: " + assembly.FullName);
	}
	foreach (var name in resourceNames)
	{
		AddResource(name, assembly);
	}
	return this;
}

private static IList GetAllHbmXmlResourceNames(Assembly assembly)
{
	var result = new List&lt;string&gt;();

	foreach (var resource in assembly.GetManifestResourceNames())
	{
		if (resource.EndsWith(".hbm.xml"))
		{
			result.Add(resource);
		}
	}

	return result;
}</pre>
<p>The answer was clear: the mappings are added to the queue (see class MappingsQueue.cs) and processed one by one in the order they were enqueued. And the order depends of the internal implementation of the GetManifestResourceNames method. Unfortunately this boils down to know the implementation of the method from System.Reflection.RuntimeAssembly that is quite hard to decompile and investigate.</p>
<pre class="brush:csharp">[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string[] GetManifestResourceNames(RuntimeAssembly assembly);</pre>
<p>However from experiments we found out that the order of returned resources depends on the order they are defined in the *.csproj file.</p>
<p>Special thanks to Grzegorz S. for taking part in our experiments.</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/14/nhibernate-processing-hbm-xml-order/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NHibernate Internals: Exploring NHibernate Proxy Part 3</title>
		<link>http://asptip.net/2013/11/08/nhibernate-internals-exploring-nhibernate-proxy-part-3/</link>
		<comments>http://asptip.net/2013/11/08/nhibernate-internals-exploring-nhibernate-proxy-part-3/#comments</comments>
		<pubDate>Fri, 08 Nov 2013 23:12:09 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate Internals]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=343</guid>
		<description><![CDATA[Introduction This is the next post from the quesi-series of notes about NHibernate Proxies. What is ProxyDummy? In the first post I introduced generated class for MyProxyImpl class implementing IMyProxy interface. One of the interesting things here is ProxyDummy class the proxy is directly inheriting from: public class INHibernateProxyProxy : ProxyDummy, INHibernateProxy, IMyProxy, ISerializable, IProxy [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This is the next post from the quesi-series of notes about <a title="NHibernate Internals: Exploring NHibernate Proxy Part 1" href="http://asptip.net/2013/11/03/nhibernate-internals-exploring-nhibernate-proxy-part-1/">NHibernate Proxies</a>.</p>
<h2>What is ProxyDummy?</h2>
<p>In the first post I introduced generated class for MyProxyImpl class implementing IMyProxy interface. One of the interesting things here is ProxyDummy class the proxy is directly inheriting from:</p>
<pre class="brush:csharp">public class INHibernateProxyProxy : ProxyDummy, INHibernateProxy, IMyProxy, ISerializable, IProxy</pre>
<p><span id="more-343"></span></p>
<p>This class has no members. It is a some kind of marker class. I search for usages in the solution but there is neither strongly typed reference nor run-time.</p>
<pre class="brush:csharp">public class ProxyDummy
{
	/* No Implementation */
}</pre>
<p>However CreateUncachedProxyType of the ProxyFactory reveals some dark side power: we find short comment describing why we inherit from the ProxyDummy class. And this is something that is self-explanatory =].</p>
<pre class="brush:csharp">// Use the proxy dummy as the base type 
// since we're not inheriting from any class type
System.Type parentType = baseType;
if (baseType.IsInterface)
{
	parentType = typeof (ProxyDummy);
	interfaces.Add(baseType);
}</pre>
<p>I believe this is something that is somehow a legacy code. Why do we need to have a concrete class in a proxy? Maybe this was intended to use in the future?</p>
<h2>What is IProxy and INHibernateProxy?</h2>
<p>The first interface - IProxy is a part of the LinFu project and it has only internal meaning for the LinFu.DynamicProxy namespace. The interface is defined as follows:</p>
<pre class="brush:csharp">namespace NHibernate.Proxy.DynamicProxy
{
	public interface IProxy
	{
		IInterceptor Interceptor { get; set; }
	}
}</pre>
<p>As we can see there is only one member defined there - IInterceptor type that is more attractive for further investigations.</p>
<p>Now is the turn for INHibernateProxy interface:</p>
<pre class="brush:csharp">namespace NHibernate.Proxy
{
	/// &lt;summary&gt;
	/// A marker interface so NHibernate can know if it is dealing with
	/// an object that is a Proxy. 
	/// &lt;/summary&gt;
	/// &lt;remarks&gt;
	/// &lt;para&gt;
	/// This interface should not be implemented by anything other than
	/// the Dynamically generated Proxy.  If it is implemented by a class then
	/// NHibernate will think that class is a Proxy and will not work.
	/// &lt;/para&gt; 
	/// &lt;para&gt;
	/// It has to be public scope because
	/// the Proxies are created in a separate DLL than NHibernate. 
	/// &lt;/para&gt; 
	/// &lt;/remarks&gt;
	public interface INHibernateProxy
	{
		/// &lt;summary&gt; Get the underlying lazy initialization handler. &lt;/summary&gt;
		ILazyInitializer HibernateLazyInitializer { get;}
	}
}</pre>
<p>As we see in the summary of the INHibernateProxy interface - it is a marker that is used by NHibernate  to recognize if it is dealing with a proxy instance. The IProxy works only for LinFu.DynamicProxy context. INHibernateProxy interface is being used through the whole NHibernate project. It is important to generate proxy type with this interface implemented to let NHibernate use this class as a proxy. Dynamically generated class had it implemented with IProxy:</p>
<pre class="brush:csharp">[Serializable]
public class INHibernateProxyProxy : ProxyDummy, <strong>INHibernateProxy</strong>, IMyProxy, ISerializable, <strong>IProxy</strong></pre>
<p>This is end for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/08/nhibernate-internals-exploring-nhibernate-proxy-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NHibernate Internals: Exploring NHibernate Proxy Part 2</title>
		<link>http://asptip.net/2013/11/07/nhibernate-internals-exploring-nhibernate-proxy-part-2/</link>
		<comments>http://asptip.net/2013/11/07/nhibernate-internals-exploring-nhibernate-proxy-part-2/#comments</comments>
		<pubDate>Thu, 07 Nov 2013 22:36:37 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate Internals]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=333</guid>
		<description><![CDATA[Introduction In the previous post I showed how simple proxy class was generated by proxy factory. Now it is time to find some answers to the questions I asked. The suspicious name of the proxy class We have a mapped class called MyProxyImpl and it implements an interface IMyProxy. The implementing proxy class name is INHibernateProxyProxy. [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In the <a title="NHibernate Internals: Exploring NHibernate Proxy Part 1" href="http://asptip.net/2013/11/03/nhibernate-internals-exploring-nhibernate-proxy-part-1/">previous post</a> I showed how simple proxy class was generated by proxy factory. Now it is time to find some answers to the questions I asked.</p>
<h2>The suspicious name of the proxy class</h2>
<p>We have a mapped class called MyProxyImpl and it implements an interface IMyProxy. The implementing proxy class name is INHibernateProxyProxy. This is strange and questionable. Let's investigate this and I will try answer the first question: Why it has such a strange name?</p>
<p><span id="more-333"></span></p>
<p>One thing that I should expand in the previous post is a mapping definition that is really important in understanding the way NHibernate maps a persistent class. In this particular case we have following mapping file defined:</p>
<pre class="brush:csharp">&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
				   assembly="NHibernate.Test"
				   namespace="NHibernate.Test.DynamicProxyTests.InterfaceProxySerializationTests"&gt;
	&lt;class name="MyProxyImpl" proxy="IMyProxy"&gt;
		&lt;id	name="Id"&gt;
			&lt;generator class="assigned" /&gt;
		&lt;/id&gt;

		&lt;property name="Name" /&gt;
	&lt;/class&gt;
&lt;/hibernate-mapping&gt;</pre>
<p>The most interesting part is the line with<strong> proxy="IMyProxy"</strong>. This line tells NHibernate that generated proxy will have to implement IMyProxy interface instead of inheriting from MyProxyImpl class.</p>
<blockquote><p>Note that the MyProxyImpl has not a virtual members and the proxy can be instantiated without errors! The reason it still works is because Proxy type is not being generated on class basis but by explicit proxy interface implementation.</p></blockquote>
<p>The definition of this mapping file is available under the <a href="http://nhforge.org/doc/nh/en/index.html#mapping-declaration-class">http://nhforge.org/doc/nh/en/index.html#mapping-declaration-class</a>. We have there an explanation:</p>
<blockquote><p><tt>proxy</tt> (optional): Specifies an interface to use for lazy initializing proxies. You may specify the name of the class itself.</p></blockquote>
<p>Description tells nothing about the generated class name, so we need to go debug through the code to see how the class name is resolved.<br />
The stack trace pointed at PocoEntityTuplizer and its behaviour during the building the proxy factory for specific class. The clue is that we have some set of the types (interfaces) that are used in the resulting proxy with the first type set to INhibernateProxy.</p>
<pre class="brush:csharp">// determine all interfaces needed by the resulting proxy
var proxyInterfaces = new HashedSet {typeof (INHibernateProxy)};</pre>
<p>So the resulting proxyInterfaces set will finally have two types of the interfaces: INHibernateProxy and the IMyProxy. This will affect of course the DefaultProxyFactory PostInstantiate method. As a result when calling GetProxy we will have to take the first interface type when the class is based on the explicit proxy interface:</p>
<pre class="brush:csharp">object proxyInstance = IsClassProxy
    ? factory.CreateProxy(PersistentClass, initializer, Interfaces)
    : factory.CreateProxy(Interfaces[0], initializer, Interfaces);</pre>
<p>The IsClassProxy tells if the mapped class should be used for generating the name of the proxy or we should use the first interface type that is always INHibernateProxy. So far so good. The mystery solved!</p>
<p>My opinion about the way we access the interface by getting Interfaces[0] is a little bit clumsy. Finally this is always INhibernateProxy, so why we are using here a reference to the first item in the interfaces array ? I should ask this question in the nh-dev group.</p>
<p>But this leads to other additional question. How this behaviour is handled if I have many similar mappings? So let's say that I 'm going to declare the similar types: MyProxyImpl2 class that implements IMyProxy2 interface. How this will work if I have the same type, assembly and module names ?<br />
After some investigations I found that NHibernate is creating the same INHibernateProxyProxy type within the INHibernateProxyAssembly in current AppDomain for IMyProxy and IMyProxy2. It would not be anything special but we have really strange fact. According to DefineDynamicAssembly signature description the assembly identity should be <a title="AppDomain.DefineDynamicAssembly Method" href="http://msdn.microsoft.com/en-us/library/vstudio/bs22fky4">unique among AppDomain</a>. As I expected this is just simply hint not requirement, so here we can have two types with the same names in the assembly with the same name and with the module as well. When we check the currentDomain.GetAssemblies() in CreateUncachedProxyType of the ProxyFactory we get the types in one app domain:</p>
<pre class="brush:csharp">[27]: {INHibernateProxyProxyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null}
[28]: {ISymWrapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[29]: {INHibernateProxyProxyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null}</pre>
<blockquote><p> It is worth to remember that NHibernate generates separate dynamic assembly with the generated type for each proxy type within one AppDomain.</p></blockquote>
<p>Ok, let's have a cold beer for that, and see you soon in the next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/07/nhibernate-internals-exploring-nhibernate-proxy-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NHibernate Internals: Exploring NHibernate Proxy Part 1</title>
		<link>http://asptip.net/2013/11/03/nhibernate-internals-exploring-nhibernate-proxy-part-1/</link>
		<comments>http://asptip.net/2013/11/03/nhibernate-internals-exploring-nhibernate-proxy-part-1/#comments</comments>
		<pubDate>Sun, 03 Nov 2013 23:22:24 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate Internals]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=323</guid>
		<description><![CDATA[Introduction This is a first post from series I plan to write about proxy feature in NHibernate. I would treat this as a notes and observation rather than a regular tutorial. I hope that you can find these quasi-posts series useful. I encourage you to make experiments with NHibernate! The version I'am working with is [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This is a first post from series I plan to write about proxy feature in NHibernate. I would treat this as a notes and observation rather than a regular tutorial. I hope that you can find these quasi-posts series useful. I encourage you to make experiments with NHibernate!<br />
The version I'am working with is 3.3.1.4000. The names here or in the next posts will refer to the test case names or types used there.</p>
<h2>NHibernate Proxy at a glance</h2>
<p>NHibernate provides enabled by default feature called lazy-loading. In a one word: this is a feature that allows to keep a non-loaded referenced entity or collection of entities attached to the entity you are working with and loading them on demand when it is necessary.</p>
<p><span id="more-323"></span><br />
NHibernate was using separate dll for the proxy factory, but now it is included in the codebase . Default proxy factory is based on the LinFu.DynamicProxy. You can see it's customized implementation under NHibernate.Proxy.DynamicProxy namespace. It is still possible of course to use your own ProxyFactory implementation. This can be done via configuration.</p>
<h2>Proxy</h2>
<p>As I mentioned above the default implementation of the  proxy factory is based on LinFu.DynamicProxy. More about this proxy generator you can find on <a title="Intro to LinFu" href="http://www.codeproject.com/Articles/20884/Introducing-the-LinFu-Framework-Part-I-LinFu-Dynam" target="_blank">codeproject</a>.  I would not like to dig in the implementation of the LinFu. Instead let's see the experimentation with the simple interface and it's implementation as a proxy class.</p>
<p>So, we have IMyProxy interface with Id and name properties and MyProxyImpl implementation. Let's see what is the output of dynamically generated type. In order to do so, go to ProxyFixture test and run the Proxy test case. You can define DEBUG constant in the NHibernate test project. Additionally change Save method body in the DefaultProxyAssemblyBuilder and choose right assembly name. The output was taken from .NET Reflector and some code was removed from the output for clarity.</p>
<pre class="brush:csharp">public interface IMyProxy
{
	int Id { get; set; }
	string Name { get; set; }
}</pre>
<pre class="brush:csharp">public class MyProxyImpl: IMyProxy
{
	public int Id { get; set; }
	public string Id { get; set; }
}</pre>
<p>And the mapping file that is the essential here is listed below as an *.hbm.xml mapping:</p>
<pre class="brush:csharp">&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
				   assembly="NHibernate.Test"
				   namespace="NHibernate.Test.DynamicProxyTests.InterfaceProxySerializationTests"&gt;
	&lt;class name="MyProxyImpl" proxy="IMyProxy"&gt;
		&lt;id	name="Id"&gt;
			&lt;generator class="assigned" /&gt;
		&lt;/id&gt;

		&lt;property name="Name" /&gt;
	&lt;/class&gt;
&lt;/hibernate-mapping&gt;</pre>
<pre class="brush:csharp">[Serializable]
public class INHibernateProxyProxy : ProxyDummy, INHibernateProxy, IMyProxy, ISerializable, IProxy
{
    // Fields
    private IInterceptor __interceptor;

    // Methods
    public INHibernateProxyProxy()
    {
    }

    public INHibernateProxyProxy(SerializationInfo info1, StreamingContext context) : this()
    {
        System.Type type = typeof(IInterceptor);
        this.__interceptor = (IInterceptor) info1.GetValue("__interceptor", type);
    }

    public override ILazyInitializer get_HibernateLazyInitializer()
    {
        if (this.Interceptor == null)
        {
            return this.HibernateLazyInitializer;
        }
        object[] args = new object[0];
        InvocationInfo info = new InvocationInfo(this, (MethodInfo) methodof(INHibernateProxy.get_HibernateLazyInitializer), null, new Type[0], args);
        args = info.Arguments;
        return (ILazyInitializer) this.Interceptor.Intercept(info);
    }

    public override int get_Id()
    {
        if (this.Interceptor == null)
        {
            return this.Id; // refers to IMyProxy.Id property
        }
        object[] args = new object[0];
        InvocationInfo info = new InvocationInfo(this, (MethodInfo) methodof(IMyProxy.get_Id), null, new Type[0], args);
        args = info.Arguments;
        return (int) this.Interceptor.Intercept(info);
    }

    public override void set_Id(int num1)
    {
        if (this.Interceptor == null)
        {
            this.Id = num1;
        }
        else
        {
            InvocationInfo info = new InvocationInfo(this, (MethodInfo) methodof(IMyProxy.set_Id), null, new Type[0], new object[] { num1 });
            this.Interceptor.Intercept(info);
            object[] arguments = info.Arguments;
        }
    }

    public override void GetObjectData(SerializationInfo info1, StreamingContext context)
    {
        info1.SetType(typeof(ProxyObjectReference));
        info1.AddValue("__interceptor", this.__interceptor);
        info1.AddValue("__baseType", "NHibernate.Proxy.INHibernateProxy, NHibernate, Version=3.3.1.4000, Culture=neutral, PublicKeyToken=null");
        info1.AddValue("__baseInterfaceCount", 2);
        info1.AddValue("__baseInterface0", "NHibernate.Proxy.INHibernateProxy, NHibernate, Version=3.3.1.4000, Culture=neutral, PublicKeyToken=null");
        info1.AddValue("__baseInterface1", "NHibernate.Test.DynamicProxyTests.InterfaceProxySerializationTests.IMyProxy, NHibernate.Test, Version=3.3.1.4000, Culture=neutral, PublicKeyToken=null");
    }

    public virtual IInterceptor NHibernate.Proxy.DynamicProxy.IProxy.Interceptor
    {
        get
        {
            return this.__interceptor;
        }
        set
        {
            this.__interceptor = value;
        }
    }
}</pre>
<p>Let's list interesting things here that I will try to explain in the next posts:</p>
<ul>
<li>The name INHibernateProxyProxy is really controversial. Why proxy class has such a strange name ?</li>
<li>The proxy inherits from ProxyDummy. What the heck is that ?</li>
<li>Here are two interfaces IProxy and INHibernateProxy. What they are here for ?</li>
<li>What is IInterceptor and how it is used in NHibernate?</li>
<li>What is ILazyInitializer and how it works ?</li>
<li>Finally, how this magic works that when I try to access Id the entity is not loaded but when I access other property, proxy tries to get value from DB (if there is no entity stored in session cache)?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/03/nhibernate-internals-exploring-nhibernate-proxy-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Castle Windsor &#8211; wprowadzenie</title>
		<link>http://asptip.net/2013/11/03/castle-windsor-wprowadzenie/</link>
		<comments>http://asptip.net/2013/11/03/castle-windsor-wprowadzenie/#comments</comments>
		<pubDate>Sun, 03 Nov 2013 22:42:40 +0000</pubDate>
		<dc:creator><![CDATA[kamil.kliczbor]]></dc:creator>
				<category><![CDATA[Castle Windsor]]></category>
		<category><![CDATA[Dependency Injection]]></category>

		<guid isPermaLink="false">http://asptip.net/?p=309</guid>
		<description><![CDATA[Wstęp WindsorCastle jest kontenerem wstrzykiwania zależności. Jest to jeden z kilku projektów http://www.castleproject.org/. W tym wpisie krótko opiszę w jaki sposób ten temat ugryźć (delikatnie). Prosta aplikacja dla fanów motoryzacji Poniższy przykład trochę naiwnie pokazuje użycie kontenera w aplikacji. W tym konkretnym przypadku chcemy stworzyć moduł bazowy dla producenta samochodów, który dostarcza standardowo wykonany samochód [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 dir="ltr">Wstęp</h2>
<p dir="ltr">WindsorCastle jest kontenerem wstrzykiwania zależności. Jest to jeden z kilku projektów <a href="http://www.castleproject.org/">http://www.castleproject.org/</a>. W tym wpisie krótko opiszę w jaki sposób ten temat ugryźć (delikatnie).</p>
<p dir="ltr"><span id="more-309"></span></p>
<h2 dir="ltr"></h2>
<h2 dir="ltr">Prosta aplikacja dla fanów motoryzacji</h2>
<p>Poniższy przykład trochę naiwnie pokazuje użycie kontenera w aplikacji. W tym konkretnym przypadku chcemy stworzyć moduł bazowy dla producenta samochodów, który dostarcza standardowo wykonany samochód wyposażony w standardowy silnik. W aplikacji chcemy mieć możliwość modyfikacji zarówno pojazdu jak i silnika w zależności od zapotrzebowania lokalnego sprzedawcy. Pomiędzy pojazdem i silnikiem zachodzą jednak pewne zależności, a ściślej rzecz ujmując samochód umie współpracować z silnikiem poprzez znany interfejs, a silnik jest kluczowy podzespołem samochodu . To co będzie się działo w samym silniku zależy od realizacje jego wykonania. Dla przykładu samochód może posiadać silnik spalinowy, elektryczny, hybrydowy etc. Takie podejście w aplikacjach biznesowych jest często stosowane i nie powinno być zaskoczeniem.<br />
W naszej aplikacji zdefiniowaliśmy interfejs ICar, a w zależności od konfiguracji kontenera chcemy podać do jego konstruktora jako zależność jakąś konkretną implementację interfejsu IEngine. Zwróćmy uwagę, że w definicji konstruktora typem przekazywanego parametru jest interfejs, a nie jego implementacja. W najprostszym przypadku mamy do czynienia tylko z jedną implementacją interfejsu ICar i IEngine. Ale może się zdarzyć, że dla różnych implementacji ICar chcemy wstrzyknąć różne implementacje interfejsu IEngine.</p>
<pre class="brush:csharp">public interface IEngine
{
	int HorsePower { get; }
}

public class Engine : IEngine
{
	public int HorsePower
	{
		get
		{
			return 100;
		} 
	}
}

public interface ICar
{
	int GetPower();
}

public class Car : ICar
{
	private readonly IEngine _engine;

	public Car(IEngine engine)
	{
		_engine = engine;
	}

	public int GetPower()
	{
		return _engine.HorsePower;
	}
}</pre>
<p>Logika klasy Car jest dosyć prosta w tym przypadku, ale równie dobrze można by zastosować bardziej skomplikowany algorytm. Co więcej, interfejs ICar zapewnia jedynie kontrakt, a zwracaną implementację interfejsu ICar można skonfigurować w kontenerze.</p>
<h3>Byty w Castle Windsor</h3>
<p>Castle w odniesieniu do powyższych interfejsów i klas wprowadza trzy pojęcia:</p>
<ul>
<li><strong>serwis</strong> - jest to abstrakcyjny kontrakt opisujący spójną jednostkę funkcjonalności; innymi słowy w naszej aplikacji interfejsy ICar oraz IEngine są serwisami, gdyż definiują tylko kontrakt, jaki implementujące je klasy muszą spełnić. W przypadku interfejsu IEngine implementujące klasy muszą posiadać właściwość, która zwróci liczbę opisującą moc silnika.</li>
<li><strong>komponent</strong> - jest to nic innego jak realizacja serwisu, tj. konkretyzacja abstrakcji funkcjonalności. W całej aplikacji może istnieć wiele komponentów, np. silnik może być spalinowy lub hybrydowy. Od konfiguracji kontenera zależy jaki komponent zostanie zwrócony dla danego serwisu.</li>
<li><strong>zależność</strong> zachodzi wtedy jeżeli komponent zależy od innych serwisów. W aplikacji samochodowej zależnością dla komponentu Car jest interfejs IEngine wstrzykiwany przez konstruktor.</li>
</ul>
<p>Istotnym elementem Castla są klasy rejestrujące serwisy i komponenety. Bez nich kontener nie wie jakich implementacji ma używać w określonym kontekście. Klasa instalatora musi implementować interfejs IWindsorInstaller. W module bazowym naszej aplikacji skonfigurujemy kontener w taki sposób, żeby dla serwisu ICar używał komponentu Car oraz analogicznie dla serwisu IEngine - Engine.</p>
<h3>Aplikacja z lotu ptaka</h3>
<p>Rozszerzymy więc naszą aplikację o kilka modułów “sprzedażowych” i sprawdzimy jak teraz się zachowa Castle. Schemat solution wraz z wylistowanymi plikami oraz zależności modułowymi są przedstawione na obrazkach poniżej.</p>
<p><a href="http://asptip.net/wp-content/uploads/2013/10/Solution.png"><img class="alignnone size-full wp-image-312" alt="Solution" src="http://asptip.net/wp-content/uploads/2013/10/Solution.png" width="244" height="532" /></a><a href="http://asptip.net/wp-content/uploads/2013/10/zaleznosci_w_modulach.png"><img alt="zaleznosci_w_modulach" src="http://asptip.net/wp-content/uploads/2013/10/zaleznosci_w_modulach.png" width="459" height="216" /></a></p>
<p>&nbsp;</p>
<p>W odniesieniu do zależności pomiędzy projektami, to wszystkie moduły muszą posiadać referencję do kontenera wstrzykiwania zależności.</p>
<p>Dodając zależności użyłem NuGet Package Managera ( jak widać na chwilę obecną aktualna wersja to 3.2.1):<br />
<img class="alignnone size-full wp-image-311" style="font-family: Consolas, Monaco, monospace; font-size: 12px; line-height: 18px;" alt="Dodaj_paczke_windsor" src="http://asptip.net/wp-content/uploads/2013/10/Dodaj_paczke_windsor.png" width="900" height="600" /></p>
<p>Zweryfikujmy w jaki sposób kontener poradzi sobie z rozwiązywaniem zależności w module StandardSeller. Gdy WindsorContainer zostanie już zinstancjonowany, wskazujemy mu skąd ma pobrać rejestracje zależności. Użyta linijka FromAssembly.Containing&lt;ICar&gt; oznacza, że chcemy pobrać wszystkie rejestracje z assembly zawierające interfejs ICar (odkrywcze, co nie ?). Metoda Resolve zwraca aktualnie zarejestrowany komponent dla serwisu ICar. W ten oto sposób na konsoli otrzymamy wartość “100”.</p>
<pre class="brush:csharp">public class CarFactoryWindsorInstaller : IWindsorInstaller</pre>
<pre class="brush:csharp">{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
		container.Register(Component.For&lt;ICar&gt;().ImplementedBy&lt;Car&gt;());
		container.Register(Component.For&lt;IEngine&gt;().ImplementedBy&lt;Engine&gt;());
	}
}</pre>
<pre class="brush:csharp">class Program
{
	static void Main(string[] args)
	{
		var container = new WindsorContainer();
		container.Install(FromAssembly.Containing&lt;ICar&gt;());
		var car = container.Resolve&lt;ICar&gt;();
		Console.WriteLine(car.GetPower());
		Console.ReadKey();
		container.Dispose();
	}
}</pre>
<p>W module “SportSeller” wymienimy samochód pozostawiając bez zmian zależność od IEngine. W implementacji SportCar różni się od zwykłego samochodu tym, że moc silnika jest dwa razy większa.</p>
<pre class="brush:csharp">public class SportCar : ICar
{
	private readonly IEngine _engine;

	public SportCar(IEngine engine)
	{
		_engine = engine;
	}

	public int GetPower()
	{
		return _engine.HorsePower * 2;
	}
}
public class SportSellerWindsorInstaller: IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
		container.Register(Component.For&lt;ICar&gt;().ImplementedBy&lt;SportCar&gt;().IsDefault());
	}
}</pre>
<p>Warto zwrócić uwagę na dwa ważne szczegóły:</p>
<ul>
<li>konieczne jest poinformowanie Castla, że chcemy używać komponentów z projektu bazowego - CarFactoryWindsorInstaller oraz z modułu sprzedaży samochodów sportowych - SportSellerWindsorInstaller</li>
<li>konieczne jest wskazanie, że to własnie klasa SportCar jest domyślnym kompontentem w tym zakresie rozwiązywania zależności tj. w module SportSeller. Realizujemy to poprzez użycie metody IsDefault(). Jeżeli metoda IsDefault() zostanie pominięta, Castle użyje pierwszego zarejestrowanego komponentu tj. Car.</li>
</ul>
<p>Rezultatem wykonania programu będzie pokazanie na konsoli wartości “200”.</p>
<pre class="brush:csharp">class Program
{
	static void Main(string[] args)
	{
		var container = new WindsorContainer();
		container.Install(new CarFactoryWindsorInstaller());
		container.Install(new SportSellerWindsorInstaller());            
		var car = container.Resolve&lt;ICar&gt;();
		Console.WriteLine(car.GetPower());
		Console.ReadKey();
		container.Dispose();
	}
}</pre>
<p>Ostatnim modułem w naszej aplikacji jest moduł sprzedaży samochodów budżetowych - BudgetSeller. W tym przypadku mamy standardowy samochód, z tą różnicą, żę jego elementem składowym jest silnik budżetowy, którego moc jest dwa razy mniejsza nic standardowego silnika. Zwróćmy uwagę, że wskazujemy kontenerowi installator z modułu CarFactory oraz wszystkie rejestracje z aktualnego modułu - FromAssembly.This(). Rezultatem wykonania programu w tym module jest wynik 50.</p>
<pre class="brush:csharp">public class BudgetEngine : IEngine
{
	public int HorsePower
	{
		get { return 50; }
	}
}

public class BudgetSellerWindsorInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
		container.Register(Component.For&lt;IEngine&gt;().ImplementedBy&lt;BudgetEngine&gt;().IsDefault());
	}
}

class Program
{
	static void Main(string[] args)
	{
		var container = new WindsorContainer();
		container.Install(new CarFactoryWindsorInstaller());
		container.Install(FromAssembly.This());
		var car = container.Resolve&lt;ICar&gt;();
		Console.WriteLine(car.GetPower());
		Console.ReadKey();
		container.Dispose();
	}
}</pre>
<h3>Podsumowanie</h3>
<p>We wpisie przedstawiłem bardzo podstawowy zarys koncepcji w CastleWindsor oraz przykładową aplikację pokazującą w jaki sposób skonfigurować i używać tego kontenera.</p>
<h3 dir="ltr">Żródła</h3>
<p dir="ltr"><a href="http://www.castleproject.org/projects/windsor/">http://www.castleproject.org/projects/windsor/</a></p>
<p dir="ltr"><a href="http://docs.castleproject.org/Windsor.MainPage.ashx">http://docs.castleproject.org/Windsor.MainPage.ashx</a></p>
<p dir="ltr"><a href="http://docs.castleproject.org/Windsor.Screencasts-Podcasts.ashx">http://docs.castleproject.org/Windsor.Screencasts-Podcasts.ashx</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://asptip.net/2013/11/03/castle-windsor-wprowadzenie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
