2010-03-15 22 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