Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
I am sure I have said this before; has anyone else noticed how little code I have written? I have quite a bit to talk about, so tonight I will just drop all my code and screen shots unaccompanied. Thereafter, we will spend the next few evening talking about exactly what was done.
First, I created the data contracts.
Second, I created the service contracts.
Third, I added a Silverlight browser project.
Fourth, I added the WPF XAML for the Silverlight front end.
<UserControl x:Class="DBinsor.Svc.WCF.Browser.Page" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:grid ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"> <Grid x:Name="LayoutRoot" Background="White" ShowGridLines="False"> <Grid.RowDefinitions> <RowDefinition Height="10" /> <RowDefinition Height="90" /> <RowDefinition Height="50*" /> <RowDefinition Height="50*" /> <RowDefinition Height="10" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="10" /> <ColumnDefinition Width="50*" /> <ColumnDefinition Width="50*" /> <ColumnDefinition Width="10" /> </Grid.ColumnDefinitions> <grid:DataGrid x:Name="CastleGrid" AlternatingRowBackground="Beige" AutoGenerateColumns="True" Grid.Row="1" Grid.Column="2" MouseLeftButtonDown="CastleGrid_MouseLeftButtonDown" /> <grid:DataGrid x:Name="ContractGrid" AlternatingRowBackground="Beige" AutoGenerateColumns="True" Grid.Row="1" Grid.Column="1" MouseLeftButtonDown="ContractGrid_MouseLeftButtonDown"/> <grid:DataGrid x:Name="ComponentGrid" AlternatingRowBackground="Beige" AutoGenerateColumns="True" Grid.Row="2" Grid.Column="2" MouseLeftButtonDown="ComponentGrid_MouseLeftButtonDown" /> <grid:DataGrid x:Name="ImplementationGrid" AlternatingRowBackground="Beige" AutoGenerateColumns="True" Grid.Row="2" Grid.Column="1" /> <grid:DataGrid x:Name="ComponentParametersGrid" AlternatingRowBackground="Beige" AutoGenerateColumns="True" Grid.Row="3" Grid.Column="2" CanUserResizeColumns="True" /> <grid:DataGrid x:Name="ContractParametersGrid" AlternatingRowBackground="Beige" AutoGenerateColumns="True" Grid.Row="3" Grid.Column="1" CanUserResizeColumns="True" /> </Grid> </UserControl>
Fifth, I hooked the WCF Service to the Silverlight browser.
using System; using System.Windows.Browser; using System.Windows.Controls; using System.Windows.Input; using DBinsor.Svc.WCF.Browser.DatabaseProxy; namespace DBinsor.Svc.WCF.Browser { public partial class Page : UserControl { DatabaseServiceContractClient _dscc; Castle _selectedCastle; Contract _selectedContract; Component _selectedComponent; public Page() { InitializeComponent(); this._dscc = new DatabaseServiceContractClient(); this._dscc.DemandCastlesCompleted += new EventHandler<DemandCastlesCompletedEventArgs>(_dscc_DemandCastlesCompleted); this._dscc.DemandComponentParametersCompleted += new EventHandler<DemandComponentParametersCompletedEventArgs>(_dscc_DemandComponentParametersCompleted); this._dscc.DemandComponentsCompleted += new EventHandler<DemandComponentsCompletedEventArgs>(_dscc_DemandComponentsCompleted); this._dscc.DemandContractParametersCompleted += new EventHandler<DemandContractParametersCompletedEventArgs>(_dscc_DemandContractParametersCompleted); this._dscc.DemandContractsCompleted += new EventHandler<DemandContractsCompletedEventArgs>(_dscc_DemandContractsCompleted); this._dscc.DemandImplementationsCompleted += new EventHandler<DemandImplementationsCompletedEventArgs>(_dscc_DemandImplementationsCompleted); LoadPrimaryTables(); } private void LoadPrimaryTables() { this._dscc.DemandCastlesAsync(); this._dscc.DemandContractsAsync(); } private void _dscc_DemandCastlesCompleted(object sender, DemandCastlesCompletedEventArgs e) { if (e.Error != null) { HtmlPage.Window.Alert(e.Error.Message); return; } if (e.Result.Count == 0) { return; } this.CastleGrid.ItemsSource = e.Result; } private void _dscc_DemandComponentParametersCompleted(object sender, DemandComponentParametersCompletedEventArgs e) { if (e.Error != null) { HtmlPage.Window.Alert(e.Error.Message); return; } if (e.Result.Count == 0) { return; } this.ComponentParametersGrid.ItemsSource = e.Result; } private void _dscc_DemandComponentsCompleted(object sender, DemandComponentsCompletedEventArgs e) { if (e.Error != null) { HtmlPage.Window.Alert(e.Error.Message); return; } if (e.Result.Count == 0) { return; } this.ComponentGrid.ItemsSource = e.Result; } private void _dscc_DemandContractParametersCompleted(object sender, DemandContractParametersCompletedEventArgs e) { if (e.Error != null) { HtmlPage.Window.Alert(e.Error.Message); return; } if (e.Result.Count == 0) { return; } this.ContractParametersGrid.ItemsSource = e.Result; } private void _dscc_DemandContractsCompleted(object sender, DemandContractsCompletedEventArgs e) { if (e.Error != null) { HtmlPage.Window.Alert(e.Error.Message); return; } if (e.Result.Count == 0) { return; } this.ContractGrid.ItemsSource = e.Result; } private void _dscc_DemandImplementationsCompleted(object sender, DemandImplementationsCompletedEventArgs e) { if (e.Error != null) { HtmlPage.Window.Alert(e.Error.Message); return; } if (e.Result.Count == 0) { return; } this.ImplementationGrid.ItemsSource = e.Result; } private void CastleGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { object temp = CastleGrid.SelectedItem; if (temp == null) { return; } this._selectedCastle = temp as Castle; this._dscc.DemandComponentsAsync(this._selectedCastle); } private void ContractGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { object temp = ContractGrid.SelectedItem; if (temp == null) { return; } this._selectedContract = temp as Contract; this._dscc.DemandImplementationsAsync(this._selectedContract); this._dscc.DemandContractParametersAsync(this._selectedContract); } private void ComponentGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { object temp = ComponentGrid.SelectedItem; if (temp == null) { return; } this._selectedComponent = temp as Component; this._dscc.DemandComponentParametersAsync(this._selectedComponent); } } }
Sixth, I used LINQ to Extract Data from the Entity Framework.
using System.Linq; namespace DBinsor.Svc.WCF.BusinessLogic { public static class DatabaseToDataContractGenerator { public static DataContracts.Castles GetCastles() { using (DataAccess.Model.Entities db = new DataAccess.Model.Entities()) { DataContracts.Castles ret = new DataContracts.Castles(); var dataCastles = from castle in db.Castle select castle; foreach (DataAccess.Model.Castle dataCastle in dataCastles) { DataContracts.Castle serviceCastle = new DataContracts.Castle(); serviceCastle.id = dataCastle.Id; serviceCastle.name = dataCastle.Name; ret.Add(serviceCastle); } return ret; } } public static DataContracts.Components GetComponents(DataContracts.Castle castle) { using (DataAccess.Model.Entities db = new DataAccess.Model.Entities()) { int temp; DataContracts.Components ret = new DataContracts.Components(); var dataComponents = from component in db.Components where component.Castle.Id == castle.id select component; foreach (DataAccess.Model.Components dataComponent in dataComponents) { DataContracts.Component serviceComponent = new DataContracts.Component(); serviceComponent.id = dataComponent.Id; int.TryParse(dataComponent.InitialPoolSize.ToString(), out temp); serviceComponent.initialPoolSize = temp; serviceComponent.inspectionBehavior = dataComponent.InspectionBehavior; serviceComponent.lifestyle = dataComponent.Lifestyle; int.TryParse(dataComponent.MaxPoolSize.ToString(), out temp); serviceComponent.maxPoolSize = temp; serviceComponent.Castle = castle; serviceComponent.Implementation = new DataContracts.Implementation(); //todo: Add Implementation Name ret.Add(serviceComponent); } return ret; } } public static DataContracts.ComponentParameters GetComponentParameters(DataContracts.Component component) { using (DataAccess.Model.Entities db = new DataAccess.Model.Entities()) { DataContracts.ComponentParameters ret = new DataContracts.ComponentParameters(); var dataComponentParameters = from componentParameter in db.ComponentParameters where componentParameter.Components.Id == component.id select componentParameter; foreach (DataAccess.Model.ComponentParameters dataComponentParameter in dataComponentParameters) { DataContracts.ComponentParameter serviceComponentParameter = new DataContracts.ComponentParameter(); serviceComponentParameter.Component = component; serviceComponentParameter.overrideValue = dataComponentParameter.OverrideValue; //todo: Add Contract Parameter Name ret.Add(serviceComponentParameter); } return ret; } } public static DataContracts.Contracts GetContracts() { using (DataAccess.Model.Entities db = new DataAccess.Model.Entities()) { DataContracts.Contracts ret = new DataContracts.Contracts(); var dataContracts = from contract in db.Contracts select contract; foreach (DataAccess.Model.Contracts dataContract in dataContracts) { DataContracts.Contract serviceContract = new DataContracts.Contract(); serviceContract.id = dataContract.Id; serviceContract.contractNamespace = dataContract.Namespace; serviceContract.contractInterface = dataContract.Interface; ret.Add(serviceContract); } return ret; } } public static DataContracts.Implementations GetImplementations(DataContracts.Contract contract) { using (DataAccess.Model.Entities db = new DataAccess.Model.Entities()) { DataContracts.Implementations ret = new DataContracts.Implementations(); var dataImplementations = from implementation in db.Implementations where implementation.Contracts.Id == contract.id select implementation; foreach (DataAccess.Model.Implementations dataImplementation in dataImplementations) { DataContracts.Implementation serviceImplementation = new DataContracts.Implementation(); serviceImplementation.name = dataImplementation.Name; serviceImplementation.Contract = contract; ret.Add(serviceImplementation); } return ret; } } public static DataContracts.ContractParameters GetContractParameters(DataContracts.Contract contract) { using (DataAccess.Model.Entities db = new DataAccess.Model.Entities()) { DataContracts.ContractParameters ret = new DataContracts.ContractParameters(); var dataContractParameters = from contractParameter in db.ContractParameters where contractParameter.Contracts.Id == contract.id select contractParameter; foreach (DataAccess.Model.ContractParameters dataContractParameter in dataContractParameters) { DataContracts.ContractParameter serviceContractParameter = new DataContracts.ContractParameter(); serviceContractParameter.name = dataContractParameter.Name; serviceContractParameter.defaultValue = dataContractParameter.DefaultValue; serviceContractParameter.Contract = contract; ret.Add(serviceContractParameter); } return ret; } } } }
Seventh, I had to add the CSDL, MSL and SSDL files to my host project to make things work. Still need to think about a better way to do this:
<connectionStrings> <add name="DBinsor.Svc.WCF.DataAccess.Properties.Settings.WindsorDataBaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\WindsorDataBase.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" /> </connectionStrings>
Finally, Here is the End Product: