See here for an example of how to implement a unit of work pattern in WCF (using Unity).
public class CustomServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new CustomServiceHost(serviceType, baseAddresses);
}
}
public class CustomServiceHost : ServiceHost
{
static IUnityContainer _container;
static CustomServiceHost()
{
_container = new UnityContainer();
_container.RegisterType<ICompanyRepository, CompanyRepository>();
_container.RegisterType<IUnitOfWork, DbUnitOfWork>();
_container.RegisterType<SVCContext>(new ServiceInstanceLifeTimeManager());
}
public CustomServiceHost(Type serviceType, params Uri[] : base(serviceType, baseAddresses)
{
}
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
Description.Behaviors.Add(_container.Resolve<UnityServiceBehavior>());
}
}
public class UnityServiceBehavior : BehaviorExtensionElement , IServiceBehavior
{
IUnityContainer _container;
public UnityServiceBehavior(IUnityContainer container) : base()
{
_container = container;
}
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
Type serviceType = serviceDescription.ServiceType;
IInstanceProvider instanceProvider = new UnityInstanceProvider(_container, serviceType);
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in dispatcher.Endpoints)
{
endpointDispatcher.DispatchRuntime.InstanceProvider = instanceProvider;
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
new UnitOfWorkMessageInspector(_container)
);
}
}
}
public void Validate(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
}
public override Type BehaviorType
{
get { return this.GetType(); }
}
protected override object CreateBehavior()
{
return this;
}
}
public class UnityInstanceProvider : IInstanceProvider
{
IUnityContainer _container;
Type _serviceType;
public UnityInstanceProvider(IUnityContainer container, Type serviceType)
{
_container = container;
_serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return _container.Resolve(_serviceType);
}
public object GetInstance(InstanceContext instanceContext)
{
return this.GetInstance(instanceContext, null);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
public interface IUnitOfWork
{
void Commit();
}
public class DbUnitOfWork : IUnitOfWork
{
SVCContext _context;
public DbUnitOfWork(SVCContext context)
{
_context = context;
}
public void Commit()
{
_context.SaveChanges();
}
}
public class UnitOfWorkMessageInspector : IDispatchMessageInspector
{
IUnityContainer _container;
public UnitOfWorkMessageInspector(IUnityContainer container)
{
_container = container;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel,
InstanceContext instanceContext)
{
return _container.Resolve<IUnitOfWork>();
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
((IUnitOfWork)correlationState).Commit();
}
}
No comments:
Post a Comment