因爲在實際開發中,Silverlight須要調用WebService完成數據的獲取,因爲以前咱們一直採用古老的ASMX方式,生成的代理類不只難以維護,並且自身沒有提供APM模式的調用方式,致使在Sinverlight中實現線程同步,很是的困難。因此這裏我採用了WCF Restful Service來完成。html
這裏咱們須要新建一個WCF Rest Service Application項目:cookie
而後在項目中,咱們刪掉原有的示例文件,添加一個QDService.cs類,並設爲Partial模式,以便於實現多用戶的協同開發。而後咱們在Global.asax中將註冊的路由修改一下:app
1: private void RegisterRoutes()
2: {
3: RouteTable.Routes.Add(new ServiceRoute("QDService", new WebServiceHostFactory(), typeof(QDService)));
4: }
這樣,當項目運行的時候,就會以QDService爲起始點運行。less
路由註冊完成後,咱們就來將Autofac集成到項目中,這裏須要集成的dll有兩個:ide
其中Autofac是主dll,Autofac.Integration.Wcf是專門針對Wcf注入而設計的擴展。安裝Autofac.Integration.Wcf的時候,咱們可使用命令:函數
Install-Package Autofac.Wcf -version 3.0.0 -project TinyFrame.WebService
因爲Autofac.Integration.Wcf 3.0.0須要Autofac 3.0.0及其以上版本的支持,而咱們用到的Autofac版本爲3.3.0的,因此咱們這裏使用Autofac.Integration.Wcf的3.0.0版本。ui
安裝完畢後,Webconfig中會自動生成以下的配置:this
1: <runtime>
2: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
3: <dependentAssembly>
4: <assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
5: <bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.0.0.0" />
6: </dependentAssembly>
7: <dependentAssembly>
8: <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
9: <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
10: </dependentAssembly>
11: </assemblyBinding>
12: </runtime>
若是運行起來的時候,提示以下錯誤:spa
未能加載文件或程序集「Autofac, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da」或它的某一個依賴項。找到的程序集清單定義與程序集引用不匹配。 (異常來自 HRESULT:0x80131040)
咱們須要將配置中的線程
1: <bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
修改爲
1: <bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.0.0.0" />
才能夠正常的運行,我不知道爲啥,還望知道的朋友們說明一下緣由。
上面的步驟進行完畢以後,咱們添加添加一個有參數的構造函數,以便於實現Autofac的構造注入:
1: public partial class QDService
2: {
3: public QDService(
4: IApplicationService appService
5: , ILoggerService logger
6: , IUserService userService
7: , IRoleService roleService
8: , IModelService modelService
9: , IOperationService operationService
10: , IModelAndOperationService modelOperationService
11: , IModelAndRoleService modelRoleService
12: , IUserAndRoleService userRoleService
13: , ICookie cookieService
14: , IMonitorService<t_base_area> baseAreaService
15: , IMonitorService<t_base> baseService
16: , IMonitorService<t_monitor_equipment_type> equipmentTypeService
17: , IMonitorService<t_monitor_equipment> equipmentService
18: , IMonitorService<t_monitor_map> baseEquipmentMapService
19: , IMonitorService<t_monitor_param> paramService
20: , IMonitorDataQueryService dataService
21: )
22: {
23: this.appService = appService;
24: this.logger = logger;
25: this.userService = userService;
26: this.roleService = roleService;
27: this.modelService = modelService;
28: this.operationService = operationService;
29: this.modelOperationService = modelOperationService;
30: this.modelRoleService = modelRoleService;
31: this.userRoleService = userRoleService;
32: this.cookieService = cookieService;
33: this.baseAreaService = baseAreaService;
34: this.baseService = baseService;
35: this.equipmentService = equipmentService;
36: this.equipmentTypeService = equipmentTypeService;
37: this.baseEquipmentMapService = baseEquipmentMapService;
38: this.paramService = paramService;
39: this.dataService = dataService;
40: }
41:
42: private readonly IApplicationService appService;
43: private readonly ILoggerService logger;
44: private readonly IUserService userService;
45: private readonly IRoleService roleService;
46: private readonly IModelService modelService;
47: private readonly IOperationService operationService;
48: private readonly IModelAndOperationService modelOperationService;
49: private readonly IModelAndRoleService modelRoleService;
50: private readonly IUserAndRoleService userRoleService;
51: private readonly ICookie cookieService;
52: private readonly IMonitorService<t_base_area> baseAreaService;
53: private readonly IMonitorService<t_base> baseService;
54: private readonly IMonitorService<t_monitor_equipment_type> equipmentTypeService;
55: private readonly IMonitorService<t_monitor_equipment> equipmentService;
56: private readonly IMonitorService<t_monitor_map> baseEquipmentMapService;
57: private readonly IMonitorService<t_monitor_param> paramService;
58: private readonly IMonitorDataQueryService dataService;
59: }
運行起來之後,提示咱們錯誤以下:
autofac the service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.
這裏我須要說明一下,在WCF中,因爲InstanceContextMode設置爲InstanceContextMode.Single的時候,須要無參構造函數,因此在本項目中,咱們的構造是帶參數的,咱們只能設置爲PerCall或者是PerSession模式。這裏咱們就設置爲PerSession模式。
設置完成後,咱們根據dudu的這篇文章中提到的步驟,一步一步的進行便可:
首先實現IInstanceProvider接口:
1: using System;
2: using TinyFrame.Services;
3: using TinyFrame.Data.DataRepository;
4: using Autofac;
5: using TinyFrame.Unitofwork;
6: using TinyFrame.Framework.Caching;
7: using TinyFrame.Framework.Logger;
8: using TinyFrame.Framework.Query;
9: using TinyFrame.Framework.Cookie;
10: using TinyFrame.Data.DataContextFactory;
11: using Autofac.Integration.Wcf;
12: using System.ServiceModel;
13: using System.ServiceModel.Dispatcher;
14: using System.ServiceModel.Channels;
15:
16: namespace TinyFrame.WebService
17: {
18: public class IocInstanceProvider:IInstanceProvider
19: {
20: Type serviceType;
21: IContainer container;
22:
23: public IocInstanceProvider(Type serviceType)
24: {
25: this.serviceType = serviceType;
26: container = RegisterDependency();
27: }
28:
29: private IContainer RegisterDependency()
30: {
31: var builder = new ContainerBuilder();
32:
33: builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
34: builder.RegisterGeneric(typeof(MonitorService<>)).As(typeof(IMonitorService<>));
35:
36: builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().WithParameter("dbContextFactory", new DbContextFactory());
37:
38: builder.RegisterType<UserService>().AsImplementedInterfaces().InstancePerLifetimeScope();
39: builder.RegisterType<ServiceNews>().AsImplementedInterfaces().InstancePerLifetimeScope();
40: builder.RegisterType<ServiceNewsType>().AsImplementedInterfaces().InstancePerLifetimeScope();
41: builder.RegisterType<ServiceProducts>().AsImplementedInterfaces().InstancePerLifetimeScope();
42: builder.RegisterType<ServiceProductType>().AsImplementedInterfaces().InstancePerLifetimeScope();
43: builder.RegisterType<ServicePublishType>().AsImplementedInterfaces().InstancePerLifetimeScope();
44: builder.RegisterType<BBSForum>().AsImplementedInterfaces().InstancePerLifetimeScope();
45: builder.RegisterType<BBSReply>().AsImplementedInterfaces().InstancePerLifetimeScope();
46: builder.RegisterType<BBSTopic>().AsImplementedInterfaces().InstancePerLifetimeScope();
47: builder.RegisterType<BBSUser>().AsImplementedInterfaces().InstancePerLifetimeScope();
48: builder.RegisterType<RoleService>().AsImplementedInterfaces().InstancePerLifetimeScope();
49: builder.RegisterType<ModelService>().AsImplementedInterfaces().InstancePerLifetimeScope();
50: builder.RegisterType<OperationService>().AsImplementedInterfaces().InstancePerLifetimeScope();
51: builder.RegisterType<ModelAndOperationService>().AsImplementedInterfaces().InstancePerLifetimeScope();
52: builder.RegisterType<DynamicQuery>().AsImplementedInterfaces().InstancePerLifetimeScope();
53: builder.RegisterType<ModelAndRoleService>().AsImplementedInterfaces().InstancePerLifetimeScope();
54: builder.RegisterType<UserAndRoleService>().AsImplementedInterfaces().InstancePerLifetimeScope();
55: builder.RegisterType<MonitorDataQueryService>().AsImplementedInterfaces().InstancePerLifetimeScope();
56: builder.RegisterType<CookieWrapper>().AsImplementedInterfaces().InstancePerLifetimeScope();
57: builder.RegisterType<LoggerService>().AsImplementedInterfaces().InstancePerLifetimeScope();
58:
59: builder.RegisterType<ApplicationService>().AsImplementedInterfaces().InstancePerLifetimeScope();
60: builder.RegisterType<QDService>().InstancePerLifetimeScope();
61:
62: builder.RegisterType<MemoryCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").SingleInstance();
63:
64: return builder.Build();
65: }
66:
67: public object GetInstance(InstanceContext instanceContext, Message message)
68: {
69: return container.Resolve(serviceType);
70: }
71:
72: public object GetInstance(InstanceContext instanceContext)
73: {
74: return GetInstance(instanceContext,null);
75: }
76:
77: public void ReleaseInstance(InstanceContext instanceContext, object instance)
78: {
79: if (instance is IDisposable)
80: ((IDisposable)instance).Dispose();
81: }
82: }
83: }
而後實現IServiceBehavior接口:
1: using System;
2: using System.ServiceModel.Description;
3: using System.ServiceModel;
4: using System.Collections.ObjectModel;
5: using System.ServiceModel.Channels;
6: using System.ServiceModel.Dispatcher;
7:
8: namespace TinyFrame.WebService
9: {
10: public class IocServiceBehavior : Attribute, IServiceBehavior
11: {
12: public void AddBindingParameters( ServiceDescription serviceDescription
13: , ServiceHostBase serviceHostBase
14: , Collection<ServiceEndpoint> endpoints
15: , BindingParameterCollection bindingParameters)
16: {
17:
18: }
19:
20: public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
21: {
22: foreach (ChannelDispatcher item in serviceHostBase.ChannelDispatchers)
23: {
24: foreach (var ed in item.Endpoints)
25: {
26: if(!ed.IsSystemEndpoint)
27: {
28: ed.DispatchRuntime.InstanceProvider = new IocInstanceProvider(serviceDescription.ServiceType);
29: }
30: }
31: }
32: }
33:
34: public void Validate(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
35: {
36: }
37: }
38: }
最後在QDService.cs類頭上,加上[IocServiceBehavior]標籤便可實現:
1: [ServiceContract]
2: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
3: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
4: [IocServiceBehavior]
5: public partial class QDService
須要注意的是,RegisterDependency方法中須要將QDService自身的實例進行注入:
1: builder.RegisterType<QDService>().InstancePerLifetimeScope();
不然的話,會拋出以下的錯誤來:
The requested service 'TinyFrame.WebService.QDService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
作完這一切以後,咱們的全部前期準備工做都已經部署停當,下面是Consume Time!!!!!!
新建一個QDData.cs類並修改類頭爲:public partial class QDService,加入以下方法:
1: [WebInvoke(Method = "GET"
2: , ResponseFormat = WebMessageFormat.Xml
3: , BodyStyle = WebMessageBodyStyle.Bare
4: , UriTemplate = "/GetAllBases/")]
5: public List<t_base> GetAllBases()
6: {
7: var result = baseService.Get(x => x.ID != string.Empty);
8:
9: //重要
10: //這裏都須要從新遍歷賦值一下,雖然我不知道爲何,可是確實起做用了
11:
12: var list = new List<t_base>();
13: result.ToList().ForEach((item) =>
14: {
15: list.Add(new t_base()
16: {
17: Area_ID = item.Area_ID,
18: Base_Area = item.Base_Area,
19: Base_Jin = item.Base_Jin,
20: Base_Name = item.Base_Name,
21: Base_Note = item.Base_Note,
22: Base_Order = item.Base_Order,
23: Base_Wei = item.Base_Wei,
24: ID = item.ID,
25: UpdateTime = item.UpdateTime
26: });
27: });
28:
29: return list;
30: }
須要說明的是,雖然咱們能夠直接利用baseService.Get方法獲取出IList<t_base>對象出來,可是咱們不可以直接經過result.ToList()進行返回,不然的話將會得不到任何輸出,只能將獲得的數據遍歷一遍,而後加入到新建的List對象中返回,纔可奏效。這裏很是奇怪,我不知道爲何。還望知道的朋友給解惑一下。
最後看看效果: