Reputation: 23
I am working on a project using windows Azure and within an worker role i want to use a webservice to submit some information to it.My question is: Can i use the webservice without adding a service reference to it? or to add it in a certain way that when i publish my project in azure i don't need to change the service reference?
Upvotes: 2
Views: 990
Reputation: 11294
You can connect directly using a channel factory. Here's a sample base repository class, which you would override, where T is your Service Contract, such as IMyService,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace pageengine.clients
{
public class RepositoryBase<T> : IDisposable
{
#region Channel
protected String roleName;
protected String serviceName;
protected String endpointName;
protected String protocol = @"http";
protected EndpointAddress _endpointAddress;
protected BasicHttpBinding httpBinding;
protected NetTcpBinding tcpBinding;
protected IChannelFactory channelFactory;
protected T client;
protected virtual AddressHeader[] addressHeaders
{
get
{
return null;
}
}
protected virtual EndpointAddress endpointAddress
{
get
{
if (_endpointAddress == null)
{
var endpoints = RoleEnvironment.Roles[roleName].Instances.Select(i => i.InstanceEndpoints[endpointName]).ToArray();
var endpointIP = endpoints.FirstOrDefault().IPEndpoint;
if(addressHeaders != null)
{
_endpointAddress = new EndpointAddress(new Uri(String.Format("{1}://{0}/{2}", endpointIP, protocol, serviceName)), addressHeaders);
}
else
{
_endpointAddress = new EndpointAddress(String.Format("{1}://{0}/{2}", endpointIP, protocol, serviceName));
}
}
return _endpointAddress;
}
}
protected virtual Binding binding
{
get
{
switch (protocol)
{
case "tcp.ip":
if (tcpBinding == null) tcpBinding = new NetTcpBinding();
return tcpBinding;
default:
//http
if (httpBinding == null) httpBinding = new BasicHttpBinding();
return httpBinding;
}
}
}
public virtual T Client
{
get
{
if (this.client == null)
{
this.channelFactory = new ChannelFactory<T>(binding, endpointAddress);
this.client = ((ChannelFactory<T>)channelFactory).CreateChannel();
((IContextChannel)client).OperationTimeout = TimeSpan.FromMinutes(2);
var scope = new OperationContextScope(((IContextChannel)client));
addCustomMessageHeaders(scope);
}
return this.client;
}
}
protected virtual void addCustomMessageHeaders(OperationContextScope operationContextScope)
{
// Overidden
}
#endregion
#region CTOR
public RepositoryBase()
{
}
#endregion
#region IDisposable Members
public virtual void Dispose()
{
if (client != null)
{
try
{
((ICommunicationObject)client).Close();
}
catch
{
try
{
((ICommunicationObject)client).Abort();
}
catch { } // Die quietly.
}
}
if (channelFactory != null)
{
try
{
channelFactory.Close();
}
catch
{
try
{
channelFactory.Abort();
}
catch { } // Die quietly.
}
channelFactory = null;
}
_endpointAddress = null;
httpBinding = null;
tcpBinding = null;
}
#endregion
}
}
You are then discovering the endpoint, which will work both in the published and emulated environments. A class extending this base might look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using pageengine.services.entities.account;
using pageengine.services;
namespace pageengine.clients.accounts
{
public class AccountsRepository : RepositoryBase<IAccounts>, IDisposable
{
#region CTOR
public AccountsRepository()
{
this.roleName = "EntitiesRole"; // Name of the role my service is on
this.endpointName = "HttpInternal"; // Name of the endpoint configured on that role. Can be internal or input, tcp or http.
this.serviceName = "Accounts.svc"; // Name of my service.
}
#endregion
}
}
Calls to your service (in this case from an MVC controller action) are then in the form of:
public ActionResult ListAccounts()
{
using (var accountsRepository = new AccountsRepository())
{
return View("ListAccounts", accountsRepository.Client.ListAccounts());
}
}
Upvotes: 3