Data Access Layer in C# using Repository and Data Mapper
Column Name | Data type |
UserID | int |
FirstName | varchar(50) |
LastName | varchar(50) |
Address | varchar(250) |
Webscale architecture, Actors, CQRS, PowerShell, DevOps, Infrastructure as Code, Continuous Delivery
Column Name | Data type |
UserID | int |
FirstName | varchar(50) |
LastName | varchar(50) |
Address | varchar(250) |
The Extensible object pattern can be used to extend existing runtime classes with new functionality or to add new state to an object. Mainly used with to extend the functionality of the extensible objects like ServiceHostBase, InstanceContext, OperationContext and IChannelContext in WCF can also be used with other .NET classes and objects.
public class ExtensibleButton : Button, IExtensibleObject<ExtensibleButton>
{
public ExtensibleButton() : base()
{
this.BackColor = Color.Gold;
this.Extensions = new ExtensionCollection<ExtensibleButton>(this);
}
#region IExtensibleObject
public IExtensionCollection<ExtensibleButton> Extensions
{
get;
private set;
}
#endregion
}
And my extension is like
public class ButtonExtension : IExtension<ExtensibleButton>
{
#region IExtension
public void Attach(ExtensibleButton owner)
{
owner.Click += new EventHandler (
delegate( Object sender, EventArgs e)
{
MessageBox.Show("Clicked!!!");
});
}
public void Detach(ExtensibleButton owner)
{
//Do nothing here
}
#endregion
}
Now later if I want to add something new to the control like changing a text after the first extension is added. All is to add another extension and then add that to the extensions collection of the new Button control like…
public class ButtonTextExtension : IExtension<ExtensibleButton>
{
#region IExtension
public void Attach(ExtensibleButton owner)
{
owner.Click += new EventHandler(
delegate(Object sender, EventArgs e)
{
owner.Text = "Another Extension";
});
}
public void Detach(ExtensibleButton owner)
{
//Do nothing
}
#endregion
}
And then change the code in the first extension to
public class ButtonExtension : IExtension<ExtensibleButton>
{
#region IExtension
public void Attach(ExtensibleButton owner)
{
owner.Click += new EventHandler (
delegate( Object sender, EventArgs e)
{
MessageBox.Show("Clicked!!!");
owner.Extensions.Add(new ButtonTextExtension());
});
}
public void Detach(ExtensibleButton owner)
{
//Do nothing here
}
#endregion
}
That’s all.
My form constructor looks like
public Form1()
{
InitializeComponent();
_demoExtBtn.Extensions.Add(new ButtonExtension());
}
You can use the Extensible pattern very effectively in all situations where you need to extend the functionality of an existing class.
The System.ServiceModel.ChannelFactory
[ServiceContract]
public interface IWCFService
{
[OperationContract]
string SayHello(Employee emp);
}
[DataContract(Namespace = "ChannelFactoryTest", Name = "Employee")]
public class Employee
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
}
public class WCFService : IWCFService
{
public string SayHello(Employee emp)
{
return "Hello " + emp.ToString();
}
}
You can use this service contract and Data Contract created from both the Client and Host application for the service.
static void Main(string[] args)
{
Uri[] baseAddresses = new Uri[] { new Uri("net.tcp://localhost:8001/") };
using (ServiceHost host = new ServiceHost(typeof(WCFService), baseAddresses))
{
host.Open();
Console.WriteLine("Service runnning...");
Console.ReadKey();
host.Close();
}
}
<configuration>
<system.serviceModel>
<services>
<service name="ChannelFactoryTest.WCFService">
<endpoint address="WCFService" binding="netTcpBinding" contract=" ChannelFactoryTest.IWCFService" />
service>
services>
system.serviceModel>
configuration>
<configuration>
<system.serviceModel>
<client>
<endpoint name="WCFServiceConfiguration" address="net.tcp://localhost:8001/WCFService" binding="netTcpBinding" contract=" ChannelFactoryTest.IWCFService" />
client>
system.serviceModel>
configuration>
static void Main(string[] args)
{
Console.WriteLine("Press any key to start...");
Console.ReadKey();
ChannelFactoryTest.IWCFService proxy = new ChannelFactory< ChannelFactoryTest.IWCFService>IWCFService>("WCFServiceConfiguration").CreateChannel();
ChannelFactoryTest.Employee emp = new ChannelFactoryTest.Employee { Id = 1, Name = "Prajeesh" };
Console.WriteLine(proxy.SayHello(emp));
((IChannel)proxy).Close();
Console.ReadLine();
}
ADO.NET Data Services enable applications to expose data as a data service that can be consumed by web clients within corporate networks and across the internet. A data service is reachable via regular HTTP requests, using standard HTTP verbs such as GET, POST, PUT and DELETE to perform CRUD operations against the service. The payload format used by the service is controllable by the application, but all options are simple, open formats such as JSON and Atom/APP.
Add a new LINQ to SQL class and name it AdventureWorksORM.dbml to the project. Drag and drop the respective tables from the AdventureWorks database for the entities.
Add a new ADO.NET Data Service class and name it AdventureWorkService.svc. Change the class definition for the AdventureWorkService class to add the AdventureWorksORMDataContext class as given below
public class AdventureWorksService : WebDataService<AdventureWorksORMDataContext>
{
public static void InitializeService(IWebDataServiceConfiguration config)
{
config.SetResourceContainerAccessRule("*", ResourceContainerRights.AllRead);
Run the web site/ web application and you can start querying the database from the URI as given below.
For getting the row 1 value for Product.
With asynchronous page support in ASP.NET, we can register one or more tasks with the RegisterAsyncTask method for the runtime to execute asynchronously. In this article I will explain how to use the async page support in ASP.NET for calling web services/ WCF services to get the data for processing.
WEB SERVICE
We will create a simple Web Service method as:
public class CustomerService : System.Web.Services.WebService
{
[WebMethod]
public Collection<Customer> GetCustomers()
{
return new Collection<Customer>
{
new Customer { CustomerID = 1, CustomerName = "Prajeesh" },
new Customer { CustomerID = 2, CustomerName = "Sachin" },
new Customer { CustomerID = 3, CustomerName = "Rahul" },
new Customer { CustomerID = 4, CustomerName = "Varun" },
new Customer { CustomerID = 5, CustomerName = "Rachel" },
new Customer { CustomerID = 6, CustomerName = "Monica" },
new Customer { CustomerID = 7, CustomerName = "Micheal" },
new Customer { CustomerID = 8, CustomerName = "John" }
};
}
}
[Serializable]
public class Customer
{
public Int32 CustomerID { get; set; }
public String CustomerName { get; set; }
}
And the proxy class generated for this web service has the Asynchronous methods generated for the GetCustomers method.
Now Compared to VS 2005 proxy generation one major difference in VS 2008 is the missing of BeginXXX and EndXXX methods. All we get for asnyc processing is:
<
public event GetCustomersCompletedEventHandler GetCustomersCompleted;
public void GetCustomersAsync() {
this.GetCustomersAsync(null);
}
public delegate void GetCustomersCompletedEventHandler(object sender, GetCustomersCompletedEventArgs e);
public partial class GetCustomersCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
private object[] results;
internal GetCustomersCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState) {
this.results = results;
}
public Customer[] Result {
get {
this.RaiseExceptionIfNecessary();
return ((Customer[])(this.results[0]));
}
}
}
Now in the asp.net code behind file to access this method we need to add few lines like:
public partial class _Default : System.Web.UI.Page
{
Collection
CustomerServiceHost.CustomerService service;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PreRenderComplete += new EventHandler(
delegate
{
_customerGridView.DataSource = customers;
_customerGridView.DataBind();
_resultLabel.Text = "Sucess";
});
service = new AsyncWebApplication.CustomerServiceHost.CustomerService();
service.GetCustomersCompleted +=
new AsyncWebApplication.CustomerServiceHost.GetCustomersCompletedEventHandler(
delegate(Object s, AsyncWebApplication.CustomerServiceHost.GetCustomersCompletedEventArgs ce)
{
customers = new Collection
});
service.GetCustomersAsync();
}
}
public override void Dispose()
{
if (service != null) service.Dispose();
base.Dispose();
}
}
WCF SERVICE
Our WCF Service consists of a ServiceContract and a DataContract like:
[ServiceContract]
public interface ICustomerWCFService
{
[OperationContract]
Collection<WCFCustomer> GetCustomers();
}
[DataContract]
public class WCFCustomer
{
[DataMember]
public Int32 CustomerID { get; set; }
[DataMember]
public String CustomerName { get; set; }
}
And the Service implementation is like
public class CustomerWCFService : ICustomerWCFService
{
public Collection<WCFCustomer> GetCustomers()
{
return new Collection<WCFCustomer>
{
new WCFCustomer { CustomerID = 1, CustomerName = "Prajeesh" },
new WCFCustomer { CustomerID = 2, CustomerName = "Sachin" },
new WCFCustomer { CustomerID = 3, CustomerName = "Rahul" },
new WCFCustomer { CustomerID = 4, CustomerName = "Varun" },
new WCFCustomer { CustomerID = 5, CustomerName = "Rachel" },
new WCFCustomer { CustomerID = 6, CustomerName = "Monica" },
new WCFCustomer { CustomerID = 7, CustomerName = "Micheal" },
new WCFCustomer { CustomerID = 8, CustomerName = "John" }
};
}
}
Now the proxy class generated using the SVCUTIL with Asynchronous options gives you the BeginXXX and EndXXX methods on which we can use the PageAsyncTask method for asp.net asnyc processing.
Code:
public partial class _Default : System.Web.UI.Page
{
PageAsyncTask customerGetAsyncTask;
List
CustomerWCFServiceProxy.ICustomerWCFService wcfService;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PreRenderComplete += new EventHandler(
delegate
{
_customerGridView.DataSource = wcfCustomers;
_customerGridView.DataBind();
_resultLabel.Text = "Sucess";
});
wcfService = new CustomerWCFServiceProxy.CustomerWCFServiceClient();
}
customerGetAsyncTask = new PageAsyncTask(
delegate(Object beginSender, EventArgs beginArgs, AsyncCallback asynCb, Object asyncState)
{
return wcfService.BeginGetCustomers(asynCb, asyncState);
},
delegate(IAsyncResult asynEndResult)
{
wcfCustomers = wcfService.EndGetCustomers(asynEndResult).ToList();
},
delegate(IAsyncResult asynTimeOutResult)
{
_resultLabel.Text = "Timeout!!!";
},
null);
RegisterAsyncTask(customerGetAsyncTask);
}
}
Note: You can also implement parallel processing for asynchronous methods using the PageAsyncTask methods by passing true as parameter in the overloaded method.