2010-03-15 21 views
1

我想用溫莎實現多租戶,我不知道如何處理這種情況:溫莎IHandlerSelector在RIA服務的Visual Studio 2010 Beta2的

我成功地使用this技術在普通ASP.NET MVC項目和思想納入RIA Services項目也是類似的。

因此,我使用IHandlerSelector,註冊了一些組件,並編寫了ASP.NET MVC視圖來驗證它在純ASP.NET MVC環境中的工作原理。它做到了!

下一步是創建一個DomainService,它在構造函數中注入了一個IRepository。此服務託管在ASP.NET MVC應用程序中。它實際上......工作原理:我可以將數據從Silverlight應用程序中取出。

示例代碼段:

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

最後一步就是看它是否工作多租戶樣:不是!奇怪的是這樣的: 使用一些代碼行並在日誌文件中寫入調試消息我驗證了正確的處理程序被選中!但是這個處理程序似乎沒有被注入到DomainService中。我總是得到第一個處理程序(這是我的SelectHandler中的邏輯)

任何人都可以驗證此行爲嗎?注射在RIA服務中不起作用嗎?或者我缺少一些基本的東西?

開發環境:Visual Studio 2010的Beta2的

在此先感謝

+0

你能再發表一些代碼嗎?像處理程序選擇器......你如何註冊東西?我不熟悉RIA服務,但你看過嗎? http://forums.silverlight.net/forums/p/95860/219611.aspx – 2010-03-16 02:51:23

回答

1

所以看來我在我的OrganizationDomainServiceFactory中做了一件非常奇怪的事情。 沒有工作的代碼是這樣的:

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; 
} 

這顯然是不工作,因爲建立一個新的集裝箱(這不應該發生)的。

行!所以我想我嘗試使用ServiceLocator來獲取對Windsor容器的引用(在WindsorControllerFactory中使用 - 這就是我稱之爲......在ASP的引導中。NET MVC應用程序),並改變了代碼如下:

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; 
} 

和猜測:它的工作原理(!!!)多租戶所應當!

我不知道的唯一的事情是:是否有另一種方式「注入」容器(構造函數注入似乎沒有在這裏工作,編譯器會抱怨)

BTW:移動的項目從VS2010Beta2到VS2010RC (有RIA服務支持),但這不應該影響結果!

0

是的,我已經看到了這個線程,我已經實現了這個。 首先想到的,我已經使用在Global.asax.cs中此行得到RIA服務檢點(在ASP.NET MVC視圖託管)

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

下面是一些代碼:

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"]; 
     } 

    } 

這裏是完整的web.config。註冊OrganizationDomainServiceFactory(它是你提到的文章的實現)

<?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> 

希望這已經足夠了。如果你想完成一個項目,我可以給你一份副本(這是一個預生產測試項目)。

非常感謝您花費的時間!

+0

OrganizationDomainServiceFactory如何瞭解Windsor?您是否使用靜態IoC網關?文章做了一個'Activator.CreateInstance ()'這似乎不正確。 – 2010-03-17 03:38:28