带有 Unity 和 EF4 CodeFirst 的 WCF Rest 服务依赖注入





0/5 (0投票)
假设您已实现领域模型和存储库,并且 Unity 已配置好(如果缺少此部分,请告诉我,我将添加到博客中,提供完整的技术栈)。传统上,它由一个 asp.net MVC3 应用程序使用。我添加了一个服务程序集,其中实现了存储库查询中的基本业务逻辑(繁重进程留给 fsharp 组件)。这看起来如下:
假设您已实现领域模型和存储库,并且 Unity 已配置好(如果缺少此部分,请告诉我,我将添加到博客中,提供完整的技术栈)。传统上,它由一个 asp.net MVC3 应用程序使用。我添加了一个服务程序集,其中实现了存储库查询中的基本业务逻辑(繁重进程留给 fsharp 组件)。这看起来如下:
public interface IExampleService
{
IEnumerable<Example> GetAll();
}
public class ExampleService : IExampleService
{
private readonly IExampleRepository ExampleRepository;
private readonly IUnitOfWork unitOfWork;
public ConfigService(IConfigRepository exampleRepository, IUnitOfWork unitOfWork)
{
this.ExampleRepository = exampleRepository;
this.unitOfWork = unitOfWork;
}
public IEnumerable<Config> GetAll()
{
var categories = ConfigRepository.GetAll();
return categories;
}
}
现在,假设您迫切希望将其与 WCF 和 Unity 连接。
就这样做。创建一个新的类文件并将以下代码粘贴进去
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.ObjectModel;
namespace Example.Rest.Helpers
{
public class IoC
{
public class UnityWebServiceHost : WebServiceHost
{
protected IUnityContainer _container;
public UnityWebServiceHost()
{
}
public UnityWebServiceHost(object singletonInstance, params Uri[] baseAddresses)
: base(singletonInstance, baseAddresses)
{
}
public UnityWebServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
protected override void OnOpening()
{
Description.Behaviors.Add(new UnityServiceBehaviour(_container));
base.OnOpening();
}
}
public class UnityInstanceProvider : IInstanceProvider
{
private readonly Type _serviceType;
private readonly IUnityContainer _container;
public UnityInstanceProvider(IUnityContainer container, Type serviceType)
{
_serviceType = serviceType;
_container = container;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return _container.Resolve(_serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
public override object GetValue()
{
return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
}
public void Dispose()
{
RemoveValue();
}
}
public class UnityServiceBehaviour : IServiceBehavior
{
private readonly IUnityContainer _container;
public UnityServiceBehaviour(IUnityContainer container)
{
_container = container;
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (var endpointDispatcher in
serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(
channelDispatcher => channelDispatcher.Endpoints))
{
endpointDispatcher.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(_container, serviceDescription.ServiceType);
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
}
}
好的,我们来设置一个 WCF REST 服务
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class ExampleApi
{
private readonly IExampleService exampleService;
public ExampleApi(IExampleService exampleService)
{
this.exampleService = exampleService;
}
public exampleApi()
{
}
[WebGet(UriTemplate = "")]
public IEnumerable<Example> GetAll()
{
var examples = exampleService.GetAll();
return examples;
}
}
现在,确保您的 WCF REST 应用程序的 global.asax 文件如下所示,以便我们使用自定义的 UnityServiceHostFactory 并注册我们的依赖项
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("ExampleApi", new UnityServiceHostFactory(), typeof(ExampleApi)));
}
private static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new IoC.HttpContextLifetimeManager<IDatabaseFactory>());
container.RegisterType<IUnitOfWork, UnitOfWork>(new IoC.HttpContextLifetimeManager<IUnitOfWork>());
// repositories
container.RegisterType<IExampleRepository, ExampleRepository>(new IoC.HttpContextLifetimeManager<IExampleRepository>());
// services
container.RegisterType<IExampleService, ExampleService>(new IoC.HttpContextLifetimeManager<IExampleService>());
}
public class UnityServiceHostFactory : WebServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var container = new UnityContainer();
RegisterTypes(container);
return new IoC.UnityWebServiceHost(container, serviceType, baseAddresses);
}
}
}
就这样,各位。