Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Are we going backwards?
Message
De
30/11/2009 18:15:31
 
 
À
30/11/2009 11:21:48
Information générale
Forum:
ASP.NET
Catégorie:
Autre
Divers
Thread ID:
01436966
Message ID:
01437002
Vues:
118
Got the same feeling using Java/Javascript. I keep telling my colleagues it feels like Foxpro 2 something all over with one difference we're using the web.

>I've been spending a lot of time lately cramming to learn Silverlight programming, using the most current published products (VS .NET 2008, Silverlight 3 and Blend.) At the same time I've been doing ongoing maintenance and development in VFP/West Wind Web Connection. The objective in both "tracks" is to hoist an application onto the Web.
>
>As I move forward on both tracks, I've become somewhat disillusioned with .NET/Silverlight development because of the amount of effort it takes to get the simplest things done, even if I'm using a framework (Ideablade) on top of .NET to make things a little bit easier.
>
>Today I read an article talking about how Microsoft's top developers prefer hand-coding over visual design, and all of a sudden my pain was explained quite clearly (http://www.computerworld.com/s/article/9141465/Microsoft_s_top_developers_prefer_old_school_coding_methods) If Microsoft's top developers prefer creating applications with a TEXT EDITOR, it is no wonder that the .NET framework tends to lean towards carpal tunnel -inducing development methodology as well.
>
>VS.NET 2010 (slated for release sometime next year) ***finally*** introduces visual design for XAML, but it still leaves a whole bunch of pain in the codebehind. While I don't fancy myself as a luddite, at times like this I seriously wonder if we are actually making much progress here with MS's programming paradigm. To illustrate the point, I have posted below code (XAML and C# codebehind) that is necessary to get a simple data query screen up and running. You don't need to try to understand the code, just take a look at the volume and the complexity, keeping in mind that the Ideablade framework I used with this application takes care of a whole lot of the heavy lifting to get data access going -- without it I would have had to write a whole bunch of additional complex code to create a data server between Silverlight and the data source. This simple screen has a few buttons to connect to the backend SQL server database, log in, fetch and filter data, save changes, and log out. It also has a grid displaying the results of the data fetches. Call me lazy, but I believe there has to be an easier way to do this.
>
>And here (drum roll) is the code I had to write by hand (albeit with the help of Intellisense):
>
>User interface handcoded with XAML
>
>
><UserControl x:Class="FirstSilverlightApp.Page"
>    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
>    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
>    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"             
>    Width="Auto" Height="Auto">
>
>  <Grid x:Name="LayoutRoot" Background="White">
>
>    <Grid.Resources>
>      <Style x:Key="grid" TargetType="data:DataGrid">
>        <Setter Property="Margin" Value="10,10,10,10" />
>        <Setter Property="Height" Value="400" />
>        <Setter Property="Width" Value="700" />
>      </Style>
>      <Style x:Key="button" TargetType="Button">
>        <Setter Property="Width" Value="80" />
>        <Setter Property="Margin" Value="2" />
>      </Style>
>    </Grid.Resources>
>
>    <StackPanel Grid.Row="0">
>      <StackPanel Orientation="Horizontal" Margin="40,15,0,15" >
>        <Button x:Name="btnConnect" Click="btnConnect_Click" Style="{StaticResource button}"  
>                    Content="Connect"  />
>        <Button x:Name="btnLogin" Click="btnLogin_Click" Style="{StaticResource button}"  
>                    Content="Login" />
>        <Button x:Name="btnFetch" Click="btnFetch_Click" Style="{StaticResource button}"  
>                    Content="Fetch" />
>        <Button x:Name="btnSave" Click="btnSave_Click" Style="{StaticResource button}"  
>                    Content="Save" />
>        <Button x:Name="btnLogout" Click="btnLogout_Click" Style="{StaticResource button}"  
>                    Content="Logout" />
>        <Button x:Name="btnReset" Click="btnReset_Click" Style="{StaticResource button}"  
>                    Content="Reset" />
>
>      </StackPanel>
>
>      <StackPanel Orientation="Horizontal" Margin="40,15,0,15" >
>        <TextBlock Margin="0,0,6,0">Query:</TextBlock>
>        <ComboBox x:Name="queryCombo" MinWidth="30"/>
>      </StackPanel>
>
>      <data:DataGrid x:Name="dg" Style="{StaticResource grid}" 
>                AutoGenerateColumns="False" HeadersVisibility="Column">
>        <data:DataGrid.Columns>
>          <data:DataGridTextColumn Binding="{Binding CustomerID}" Header="Id" IsReadOnly="True" />
>          <data:DataGridTextColumn Binding="{Binding CompanyName}" Header="Company" />
>          <data:DataGridTextColumn Binding="{Binding ContactName}" Header="Contact" />
>          <data:DataGridTextColumn Binding="{Binding ContactTitle}" Header="Title" />
>          <data:DataGridTextColumn Binding="{Binding Address}"  Header="Address"/>
>        </data:DataGrid.Columns>
>      </data:DataGrid>
>
>      <Border BorderThickness="1" Margin="10" BorderBrush="Black">
>        <TextBox x:Name="txtStatus" Width="300" Height="25" TextWrapping="Wrap" BorderThickness="0"
>                   VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
>                   HorizontalAlignment="Left" Margin="5"  IsReadOnly="True"  />
>      </Border>
>
>    </StackPanel>
>
>  </Grid>
></UserControl>
>
>
>Codebehind -- business rules and data access coded with C#
>
>
>#region usings
>using System.Collections;
>using System.Collections.Generic;
>using System.Linq;
>using System.Windows;
>using System.Windows.Controls;
>using IdeaBlade.EntityModel;
>
>using DomainModel;
>
>#endregion
>
>namespace FirstSilverlightApp {
>
>  public partial class Page : UserControl {
>
>    #region ctor & load
>
>    public Page() {
>      InitializeComponent();
>      Loaded += Page_Loaded;
>    }
>
>    void Page_Loaded(object sender, RoutedEventArgs e) {
>      CreateEntityManager(); // the gateway to persistence
>      InitializeQueries();
>      Reset();
>    }
>
>    private void CreateEntityManager() {
>      WriteMessage("Creating EntityManager ...");
>      _entityManager = new DomainModelEntityManager(false);
>    }
>
>
>    #endregion
>
>    #region Button Click Handlers
>
>    private void btnConnect_Click(object sender, RoutedEventArgs e) {
>      Connect(); // to the server
>    }
>
>    private void btnLogin_Click(object sender, RoutedEventArgs e) {
>      Login(); // for security and identification
>    }
>
>    private void btnFetch_Click(object sender, RoutedEventArgs e) {
>      Fetch(); // Get from the database
>    }
>
>    private void btnSave_Click(object sender, RoutedEventArgs e) {
>      Save();
>    }
>
>    private void btnLogout_Click(object sender, RoutedEventArgs e) {
>      Logout();
>    }
>
>    private void btnReset_Click(object sender, RoutedEventArgs e) {
>      Reset();
>    }
>    #endregion
>
>    #region Initializequeries
>
>    private void InitializeQueries() {
>      AddQueries();
>      InitializeQueryCombo();
>    }
>
>    private void InitializeQueryCombo() {
>      var qNames = _queries.Keys.ToList();
>      queryCombo.ItemsSource = qNames;
>      queryCombo.SelectedItem = qNames.FirstOrDefault();
>      queryCombo.SelectionChanged += delegate { Fetch(); };
>    }
>
>    #endregion
>
>    #region Fetch
>
>    private void Fetch() {
>
>      var query = GetQuery();
>      if (null == query) {
>        WriteMessage("No query selected; pick a query.");
>        return;
>      }
>
>      WriteMessage("Fetching ...");
>
>      _entityManager.ExecuteQueryAsync(
>        query,
>        args => {
>          if (args.Error != null) {
>            WriteMessage(args.Error.Message);
>          } else {
>            dg.ItemsSource = args.Result;
>            ReportFetchCount(args.Result);
>          }
>        },
>        null);
>    }
>
>    private IEntityQuery GetQuery() {
>      var queryName = (string)queryCombo.SelectedItem;
>      return queryName == null ? null : _queries[queryName];
>    }
>
>    private void ReportFetchCount(IEnumerable result) {
>      WriteMessage(string.Format("Retrieved {0} customers", ((ICollection)result).Count));
>    }
>
>    #endregion
>
>    #region Queries 
>
>    private void AddQueries() {
>
>      _queries = new Dictionary<string, IEntityQuery>();
>
>      _queries.Add("Get all Customers", _entityManager.Customers);
>
>      _queries.Add("Get Customers starting with A",
>                  _entityManager.Customers
>                    .Where(c => c.CompanyName.StartsWith("A")));
>
>      _queries.Add("Get Customers with Orders in Oregon",
>                  _entityManager.Customers
>                    .Where(c => c.Orders.Any(o => o.ShipRegion == "OR")));
>
>      _queries.Add("Get Customers starting with B from cache-only",
>                  _entityManager.Customers
>                    .Where(c => c.CompanyName.StartsWith("B"))
>                    .With(QueryStrategy.CacheOnly));
>    }
>
>    #endregion
>
>    #region Reset
>
>    private void Reset() {
>
>      // Start all over again ...
>
>      btnLogin.IsEnabled = false;
>      btnFetch.IsEnabled = false;
>      btnLogout.IsEnabled = false;
>      btnSave.IsEnabled = false;
>      queryCombo.IsEnabled = false;
>
>      dg.ItemsSource = null;
>
>      _entityManager.Clear();
>      if (_entityManager.IsLoggedIn) Logout();
>      if (_entityManager.IsConnected) _entityManager.Disconnect();
>
>      WriteMessage("Ready to connect ...");
>    }
>
>    #endregion
>
>    #region Connect
>
>    private void Connect() {
>
>      _entityManager.ConnectAsync(
>        args => {
>          if (args.Error != null) {
>            WriteMessage(args.Error.Message);
>          } else {
>            WriteMessage("Connected");
>          }
>          btnLogin.IsEnabled = args.IsCompleted;
>          if (args.IsCompletedSynchronously) return;
>        },
>        null);
>
>      if (!_entityManager.IsConnected) WriteMessage("Connecting ...");
>    }
>
>    #endregion
>
>    #region Login
>
>    private void Login() {
>      var cred = new LoginCredential("demo", "demo", "demo");
>
>      WriteMessage("Logging in ...");
>
>      _entityManager.LoginAsync(
>        cred,
>        args => {
>          if (args.Error != null) {
>            WriteMessage(args.Error.Message);
>          } else {
>            WriteMessage("Logged in");
>          }
>          queryCombo.IsEnabled = args.IsCompleted;
>          btnFetch.IsEnabled = args.IsCompleted;
>          btnSave.IsEnabled = args.IsCompleted;
>          btnLogout.IsEnabled = args.IsCompleted;
>        },
>        null);
>    }
>
>    #endregion
>
>    #region Logout
>
>    private void Logout() {
>      WriteMessage("Logging out ...");
>
>      _entityManager.LogoutAsync(
>        args => {
>          WriteMessage("Logged out");
>          queryCombo.IsEnabled = false;
>          btnFetch.IsEnabled = false;
>          btnSave.IsEnabled = false;
>        },
>        null);
>    }
>
>    #endregion
>
>    #region Save
>
>    private void Save() {
>
>      if (!_entityManager.HasChanges()) {
>        WriteMessage("No changes to save.");
>        return;
>      }
>
>      WriteMessage("Saving ...");
>
>      _entityManager.SaveChangesAsync(
>        args => {
>          if (args.IsCompleted) {
>            WriteMessage("Changes saved");
>          } else {
>            WriteMessage(args.Error.Message);
>          }
>        },
>        null);
>    }
>
>    #endregion
>
>    #region Misc
>
>    private void WriteMessage(string msg) {
>      txtStatus.Text = msg;
>    }
>
>    #endregion
>
>    #region Fields
>
>    private DomainModelEntityManager _entityManager;
>    private Dictionary<string, IEntityQuery> _queries;
>
>    #endregion
>  }
>}
>
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform