2010-03-15 5 views
1

Je souhaite mettre en œuvre la location multistandard en Windsor et je ne sais pas comment gérer cette situation:Windsor IHandlerSelector dans Services RIA Visual Studio 2010 Beta2

i utilisé avec succès this technique dans la plaine des projets ASP.NET MVC et pensée incorporer dans un projet RIA Services serait similaire. J'ai donc utilisé IHandlerSelector, enregistré certains composants et écrit une vue ASP.NET MVC pour vérifier qu'elle fonctionne dans un environnement ASP.NET MVC ordinaire. Et c'est fait!

L'étape suivante consistait à créer un DomainService dans lequel un IRepository était injecté dans le constructeur. Ce service est hébergé dans l'application ASP.NET MVC. Et ça fonctionne ... en fait: je peux obtenir des données à partir d'une application Silverlight.

extrait de l'échantillon:

public OrganizationDomainService(IRepository<Culture> cultureRepository) 
{ 
      this.cultureRepository = cultureRepository; 
} 

La dernière étape est de voir si cela fonctionne à plusieurs comme locataire: il ne fait pas! La chose étrange est la suivante: en utilisant une ligne de code et en écrivant des messages de débogage dans un fichier journal J'ai vérifié que le gestionnaire correct est sélectionné! MAIS ce gestionnaire ne semble pas être injecté dans le DomainService. J'ai TOUJOURS le premier gestionnaire (c'est la logique dans mon SelectHandler)

Quelqu'un peut-il vérifier ce comportement? L'injection ne fonctionne pas dans les services RIA? Ou est-ce que je manque quelque chose de basique?

Environnement de développement: Visual Studio 2010 Beta2

Merci à l'avance

+0

Pouvez-vous poster plus de code? comme le sélecteur de gestionnaire ... et comment vous enregistrez des choses? Je ne suis pas familier avec les services RIA, mais avez-vous vu cela? http://forums.silverlight.net/forums/p/95860/219611.aspx –

Répondre

1

Donc, il semble que j'ai fait une chose très étrange dans mon OrganizationDomainServiceFactory. Le code qui ne fonctionne est la suivante:

public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context ) 
{ 
WindsorContainer container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); 
IRepository<Culture> cultureRepository = container.Resolve<IRepository<Culture>>(); 
IRepository<Currency> currencyRepository = container.Resolve<IRepository<Currency>>(); 

DomainService ds = (DomainService)Activator.CreateInstance(domainServiceType, new object[] { cultureRepository,currencyRepository }); 

ds.Initialize(context); 
return ds; 
} 

Ceci est apparemment ne fonctionne pas, à cause de la création d'un nouveau conteneur (qui ne devrait pas avoir lieu).

OK! J'ai donc essayé d'utiliser ServiceLocator pour obtenir une référence au conteneur Windsor (utilisé dans WindsorControllerFactory - c'est comme ça que je l'appelle ... dans le démarrage de l'ASP.l'application NET MVC), et a changé le code à ceci:

public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context ) 
{ 
IRepository<Culture> cultureRepository = ServiceLocator.Current.GetInstance<IRepository<Culture>>(); 
IRepository<Currency> currencyRepository = ServiceLocator.Current.GetInstance<IRepository<Currency>>(); 

DomainService ds = (DomainService)Activator.CreateInstance(domainServiceType, new object[] { cultureRepository,currencyRepository }); 

ds.Initialize(context); 
return ds; 
} 

et devinez quoi: il fonctionne (!!!) multi-location comme il devrait l'être!

La seule chose que je ne sais pas est: est-il une autre façon de « injecter » le conteneur (injection constructeur ne semble pas travailler ici, le compilateur se plaint)

BTW: déplacé le projet de VS2010Beta2 à VS2010RC (avec le support de RIA Services), mais cela ne devrait pas affecter le résultat!

0

Oui, je l'ai vu ce fil et je l'ai déjà mis en oeuvre. Tout d'abord ont à l'esprit que je l'ai utilisé cette ligne dans Global.asax.cs pour obtenir les services RIA bien se conduire (hébergé dans une vue ASP.NET MVC)

routes.IgnoreRoute("{*allsvc}", new { allsvc = @".*\.svc(/.*)?" }); 

Voici un code:

public class HostBasedComponentSelector : IHandlerSelector 
    { 
     private readonly Type[] selectableTypes; 

     public HostBasedComponentSelector(params Type[] selectableTypes) 
     { 
      this.selectableTypes = selectableTypes; 
     } 



     public bool HasOpinionAbout(string key, Type service) 
     { 
      foreach (var type in selectableTypes) 
      { 
       if (service == type) return true; 
      } 
      return false; 
     } 

     public IHandler SelectHandler(string key, Type service, IHandler[] handlers) 
     { 
      //only for debug 
      StreamWriter sw = new StreamWriter(@"c:\temp\Debug.log",true); 
      sw.WriteLine(DateTime.Now + " " + service.Name + " " + GetHostname()); 
      sw.WriteLine("Available handlers"); 
      foreach(IHandler h in handlers) 
      { 
       sw.WriteLine ("Handler "+h.ComponentModel.Name); 
      } 

      var id = string.Format("{0}:{1}", service.Name, GetHostname()); 
      var selectedHandler = handlers.Where(h => h.ComponentModel.Name == id).FirstOrDefault() ?? 
            GetDefaultHandler(service, handlers); 

      sw.WriteLine("Selected handler " + selectedHandler.ComponentModel.Name); 
      sw.WriteLine("----------- END ----------"); 
      sw.Flush(); 
      sw.Close(); 


      return selectedHandler; 
     } 
     private IHandler GetDefaultHandler(Type service, IHandler[] handlers) 
     { 
      if (handlers.Length == 0) 
      { 
       throw new ApplicationException("No components registered for service {0} With service.Name" + service.Name); 
      } 
      return handlers[0]; 
     } 

     protected string GetHostname() 
     { 
      return HttpContext.Current.Request.ServerVariables["SERVER_NAME"]; 
     } 

    } 

Voici le fichier web.config complet. Avis enregistrement du OrganizationDomainServiceFactory (il est la mise en œuvre de l'article que vous avez mentionné)

<?xml version="1.0"?> 
<!-- 
    For more information on how to configure your ASP.NET application, please visit 
    http://go.microsoft.com/fwlink/?LinkId=152368 
    --> 
<configuration> 
    <configSections> 
    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,Castle.Windsor"/> 
    </configSections> 
    <connectionStrings> 
    <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/> 
    </connectionStrings> 
    <castle> 
    <properties> 
     <sqlConnStr> 
     <!--metadata=res://*/WebShop.csdl|res://*/WebShop.ssdl|res://*/WebShop.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\SQLEXPRESS;Initial Catalog=iWebShop;User ID=sa;Password=xxx;MultipleActiveResultSets=True"--> 
     </sqlConnStr> 
    </properties> 
    <components>   
     <component id="CommonObjectContext" service="TestRIA1.Abstract.IObjectContext, TestRIA1" type="TestRIA1.Concrete.ObjectContextAdapter, TestRIA1" lifestyle="PerWebRequest"> 
     </component> 

     <component id="IConnectionStringProvider:test.gammasys.gr" service="TestRIA1.Abstract.IConnectionStringProvider, TestRIA1" type="TestRIA1.Concrete.ConnectionStringProvider, TestRIA1" lifestyle="transient"> 
     <parameters> 
      <ConnectionString> 
      metadata=res://*/WebShop.csdl|res://*/WebShop.ssdl|res://*/WebShop.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\SQLEXPRESS;Initial Catalog=iWebShop;User ID=sa;Password=xxx;MultipleActiveResultSets=True" 
      </ConnectionString> 
     </parameters> 
     </component> 

     <component id="IConnectionStringProvider:test.deltasys.gr" service="TestRIA1.Abstract.IConnectionStringProvider, TestRIA1" type="TestRIA1.Concrete.ConnectionStringProvider, TestRIA1" lifestyle="transient"> 
     <parameters> 
      <ConnectionString> 
      metadata=res://*/WebShop.csdl|res://*/WebShop.ssdl|res://*/WebShop.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\SQLEXPRESS;Initial Catalog=iWebShop2;User ID=sa;Password=xxx;MultipleActiveResultSets=True" 
      </ConnectionString> 
     </parameters> 
     </component> 

     <component id="Commonrepository" service="TestRIA1.Abstract.IRepository`1, TestRIA1" type="TestRIA1.Concrete.Repository`1, TestRIA1" lifestyle="PerWebRequest"/> 

     <component id="urlbased.handlerselector" service="Castle.MicroKernel.IHandlerSelector, Castle.MicroKernel" type="TestRIA1.HostBasedComponentSelector, TestRIA1" lifestyle="transient"> 
     <parameters> 
      <selectableTypes> 
      <array> 
       <item>TestRIA1.Abstract.IConnectionStringProvider, TestRIA1</item> 
      </array> 
      </selectableTypes> 
     </parameters> 
     </component> 

    </components> 
    </castle> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0"> 
     <assemblies> 
     <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     </assemblies> 
    </compilation> 
    <authentication mode="Forms"> 
     <forms loginUrl="~/Account/LogOn" timeout="2880"/> 
    </authentication> 
    <membership> 
     <providers> 
     <clear/> 
     <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/"/> 
     </providers> 
    </membership> 
    <profile> 
     <providers> 
     <clear/> 
     <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/> 
     </providers> 
    </profile> 
    <roleManager enabled="false"> 
     <providers> 
     <clear/> 
     <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/"/> 
     <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/"/> 
     </providers> 
    </roleManager> 
    <pages> 
     <namespaces> 
     <add namespace="System.Web.Mvc"/> 
     <add namespace="System.Web.Mvc.Ajax"/> 
     <add namespace="System.Web.Mvc.Html"/> 
     <add namespace="System.Web.Routing"/> 
     </namespaces> 
    </pages> 

    <httpHandlers> 
     <add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc.MvcHttpHandler"/> 

    </httpHandlers> 
    <httpModules> 
     <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule,Castle.MicroKernel " /> 
     <add name="DomainServiceModule" type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 

    </httpModules> 
    </system.web> 
    <system.webServer> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <modules runAllManagedModulesForAllRequests="true"> 
     <add name="DomainServiceModule" preCondition="managedHandler" 
     type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     <remove name="PerRequestLifestyle"/> 
     <add name="PerRequestLifestyle" preCondition="managedHandler" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule,Castle.MicroKernel" /> 
     <!--to get IoC initialization of DomainService --> 
     <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add name="OrganizationDomainServiceFactory" type="TestRIA1.OrganizationDomainServiceFactory"/> 
     <!-- End of IoC initial..... --> 

    </modules> 
    <handlers> 
     <remove name="MvcHttpHandler" /> 
     <add name="MvcHttpHandler" preCondition="integratedMode" verb="*" 
     path="*.mvc" type="System.Web.Mvc.MvcHttpHandler" /> 
    </handlers> 
    </system.webServer> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/> 
     <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
    <system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
    </system.serviceModel> 
</configuration> 

Espérons que cela est suffisant. Dans le cas où vous voudriez avoir le projet complet je peux vous envoyer une copie (ceci est un projet d'essai de pré-production).

Merci beaucoup pour le temps que vous passez!

+0

Comment OrganizationDomainServiceFactory connaît-il Windsor? Utilisez-vous une passerelle IoC statique? L'article fait un 'Activator.CreateInstance ()' qui ne semble pas correct. –

Questions connexes