Archive

Posts Tagged ‘DLR’

A WPF - IronRuby Scripting Console User Control

May 30th, 2009 Simon Segal 3 comments

One of the clear value added possibilities with IronRuby and IronPython (or any DLR language) has to offer is making applications scriptable. This opens the possibility for enabling scripting of your application, it’s types and potentially objects running in memory in your application at runtime. I recently went looking for an IronRuby console / shell window control written natively in WPF and turned up nothing. I did however come across some examples implemented for Windows Forms and the one that got my attention was Orion Edwards Embedded IronRuby Interactive Console.

Whilst Orion’s project provided the basis of what I was after, I was under no illusion that I would find exactly what I was after and would therefore have to build out the rest of the functionality I required.

The Basic Requirements List

  • Reusable WPF User Control
  • The Console should allow users to write script against in memory objects of the host application.
  • Should persist (to a log) the state of variables in the IronRuby runtime scopes.
  • Extensible Application Design and easily maintained and Testable.

So rather than re-invent the wheel I started out with Orion’s code and worked it into a WPF User Control that followed the MVP pattern. This version supports printing of all scope variable state to the console window, clearing of the console window text and all the out of the box access to the IronRuby runtime from the console itself. The IronRuby Console User control also allows the consumer application to pass through in memory variables from your managed CLR hosting application.

ir_console_for_wpf

Finally I need to also make mention that some of the classes used to stream the STD/IO came directly from Ben Halls wonderful IronEditor. And before I forget, the code can found here on my blogs subversion repository.

Share/Save/Bookmark

Categories: DLR, IronRuby, WPF, XAML Tags: , , ,

Entity Framework Profiler with IronRuby and IronPython Scripting

April 18th, 2009 Simon Segal 5 comments

ir_console_ef_profilerBecause I would like to write my Repositories and monitor their behaviour in the Profiler I decided that I could kill two birds with one console (so to speak). The first bird to kill involved my spending as much time as possible in the pursuit of both learning IronRuby and gaining better understanding of the more interesting problems that can be solved with dynamic languages implemented on top of the DLR. I can see the possibilities of hosting the DLR to provide scripting support to applications and after having implemented my own hosted IronRuby consoles I eventually decided to reuse one that was more fully featured, saving me quite a bit of time by best fitting the Profiler’s needs. The console I chose in the end was IronEditor which is available on codeplex. IronEditor is implemented as a Windows Forms application and so I did have to refactor it a little to make it work as User Control and have the UI behave correctly for asynchronous updates to the UI. Hosting the Windows User Control in the WPF Profiler was of course simple enough by leveraging the WindowsFormsHost.

I had already posted about what to expect from the next iteration of the Profiler and I won’t repeat it here, so if your new to the tool I suggest you look here. One further change I flagged was to remove WCF from the application and have the messaging occur via sockets. I decided against that change and chose instead (see below) to take the opportunity to demonstrate how to use WCF UnTyped Messages with a bit of IoC to achieve a more loosely coupled approach to handling messages. This approach requires writing specific handlers for specific messages that are not in any way coupled to the signature of any RPC / CRUD looking ServiceContract or the shape of any DataContract, and it is a style somewhat (largely) borrowed from NServiceBus. Here’s the code from the WCF Service and I will have more to say on that a bit later with a more detailed post.

Messaging

public void SendAny(Message message)
{
    object msg_in_body = null;

    var container =
        new Castle.Windsor.WindsorContainer();

    //get all the potential handlers in the assembly
    //NOTE: could load all these up at startup and call
    //to find one that matches from memory rather than
    //in the same iteration that adds the components
    //to the container.
    var libTypes = from a in Assembly.GetExecutingAssembly().GetTypes()
                   from i in a.GetInterfaces()
                   from ii in i.GetInterfaces()
                   from g in i.GetGenericArguments()
                   from gi in g.GetInterfaces()
                   where ii.IsAssignableFrom(typeof(IMessageHandler))
                   where gi.IsAssignableFrom(typeof(IMessage))
                   select new
                   {
                       TheType = a,
                       TheIface = i,
                       TheGeneric = g,
                       TheGenericIface = gi
                   };

    //iterate all the handlers
    foreach (var gen in libTypes)
    {
        container.AddComponent(gen.TheType.Name, gen.TheType);
        //attempt to deserialize using the current
        //handlers generic argument (the message)
        msg_in_body =
            MessageSerializer.DeserializeMessage
            (message, gen.TheGeneric);
        if (msg_in_body != null)
        {
            //resolve the message handler in the container
            var the_handler =
                container.Resolve(gen.TheType);
            var handle_method =
                the_handler.GetType().GetMethod(“Handle”);
            if(handle_method != null)
                handle_method.Invoke(the_handler,
                    new[] { msg_in_body });
        }
    }
}

The Messages And Message Handlers

public interface IMessage
{
    Guid MessageID { get; }
}

public interface IMessageHandler {  }

public interface IMessageHandler<TMessage> :
                 IMessageHandler where TMessage : IMessage
{
    void Handle(TMessage message);
}

public class EntityInterceptMessage : IMessage
{
    [XmlElement(Order = 1)]
    public Guid MessageID
    {
        get { return _id; }
        set { _id = value; }
    }

    [XmlElement(Order = 2)]
    public string SqlQueryText
    {
        get { return _sql; }
        set { _sql = value; }
    }

    [XmlElement(Order = 3)]
    public string ProcessID
    {
        get { return _processId; }
        set { _processId = value; }
    }

    //….message members etc

}

public class EntityInterceptMessageHandler :
             IMessageHandler<EntityInterceptMessage>
{
    public void Handle(EntityInterceptMessage message)
    {
        ProfilerModel.EntityMessages.Add(message);
        Console.WriteLine(message.EntityModelName);
    }
}

Running the Application

You can run this code and test it using a supplied IronRuby script named “run_profiler_script.rb”, just make sure you have the Northwind database installed , that the script gets the required changes to match your database details and that the the test projects DLL is ‘required’ from the appropriate location on your hard drive.

require ‘D:/simon.segal/Local Working/Org.TechA.EF.Profiler’ +
    ‘/Org.TechA.EF.Profiler.Tests/bin/Debug’ +
    ‘/Org.TechA.EF.Profiler.Tests.dll’

By downloading you will be accepting the code project open license for the SQL CodeBox control and the Apache License 2.0 for IronEditor, both of which have been integrated into this solution. You can download the Profiler from here.

UPDATE: (Sunday April 19th)

Apologies for having an earlier link to the code being incomplete. The problem has now been rectified.

Share/Save/Bookmark

GOF Series: Episode #4 [The Builder Pattern] - In IronRuby

November 5th, 2008 Simon Segal 3 comments

So first up let me say that the balance of this series of posts on patterns will be presented using either C# or IronRuby as languages to express the GOF patterns. Why IronRuby you ask? I have taken to learning IronRuby and Silverlight as deeply as possible this year and decided to spice things up for myself by incorporating it in this series of posts. Never fear I will continue to demonstrate most of the remaining patterns in C# but will from time to time present the patterns in both languages. For now however it’s the Builder Pattern exclusively in IronRuby for the dynamic language enthusiasts.

IronRuby is a dynamically typed, object oriented language and runs in the Dynamic Language Runtime. We will demonstrate the builder pattern using IronRuby, Windows Forms and the Ruby In Steel plugin for Visual Studio.Net 2008.

The goal of the Builder Pattern is to separate or abstract away the construction of an object and to allow the same / common construction process to create the object regardless of its representation. The different representations of the object being constructed are created by concrete builders, specifically designed to create one and only one representation of the product class.

The players in the story:

  • The Director

    • Responsible for constructing the Product object via an interface (mixin in the case of this example using IronRuby) implemented by a concrete builder.
  • The Builder

    • Provides the interface (object in this case) that creates the Product(s) constituent parts and is implemented (included as a mixin with IronRuby) by concrete builders.
  • The Concrete Builder

    • Builds the constituent parts of the Product object.
  • The Product

    • The object whose parts are created by the concrete builder.

BuilderPattern

In C# or other statically typed languages such as java, the builder pattern relies on an abstract class design and inheritance. In IronRuby there is no concept of an interface therefore a different approach is required. We can use a mixin to provide the common behavioural aspects and use arguments to diverge the different concrete builders. The construction of the ‘Product’ is abstracted from the ‘Director’ by the ‘Builder’ and it’s Concrete implementations. To obtain different representations of the Product object new concrete builder objects are created. The Builder Pattern creates it’s Product object in parts via the Director and Builders abstract signatures, however an alternate approach with IronRuby is to substitute the abstract class for a mixin.

#Product
class FootballTeam

    def team_id?()
        self.hash
    end

    def team_type_name?()
        @team_type_name
    end

    def team_properties?()
        @team_properties
    end

    def initialize(name)
        @team_type_name = name
        @team_properties = Hash.new(“Staff Role does not exist!”)
    end

end

#Builder
module FootballTeamBuilder

    attr_reader :name
    attr_writer :name

    def footy_team?()
        @footy_team
    end

    def build_init()
        @footy_team = FootballTeam.new(name)
    end

    def build_players(number_of_players)
        @footy_team.team_properties?["Players"] = number_of_players
    end

    def build_ball_shape(shape_of_ball)
        @footy_team.team_properties?["ballshape"] = shape_of_ball
    end

    def build_games_per_season(number_of_games)
        @footy_team.team_properties?["games"] = number_of_games
    end

    def print_team_details()

        attributes =  “****************************” +
            “******************************\r\n”

        attributes += “Created a #{name} team with the “ +
            “following attributes :\r\n”

        @footy_team.team_properties?.each { |k,v|
            attributes += k.to_s + ” “ + v.to_s + “\r\n” }

        attributes += “\n***************************” +
            “*******************************\n”

        return attributes
    end

end

#Concrete Builder”
class AustralianRulesFootballTeamBuilder 

    include FootballTeamBuilder

    def build_all()
        self.name = “Aussie Rules”
        build_init()
        build_ball_shape(“Oval”)
        build_games_per_season(22)
        build_players(18)
    end

end

#Concrete Builder
class RugbyLeagueFootballTeamBuilder

    include FootballTeamBuilder

   def build_all()
        self.name = “Rugby League”
        build_init()
        build_ball_shape(“Oval”)
        build_games_per_season(24)
        build_players(13)
    end

end

#Concrete Builder
class SoccerFootballTeamBuilder

    include FootballTeamBuilder

    def build_all()
        self.name = “Soccer”
        build_init()
        build_ball_shape(“Round”)
        build_games_per_season(44)
        build_players(11)
    end

end

#Director Class
class GoverningBody

    def build_football_team(football_team_builder)
        unless football_team_builder.is_a?(FootballTeamBuilder)
            fail NoNewMethodError.new(“Cannot build with arguments that are “ +
                “not FootballTeamBuilder class objects”)
        end
        football_team_builder.build_all
    end

end
 
Here’s our form and its form load event method.
 
def Form1_Load(sender, e)

      #new up a Director
      f = GoverningBody.new

      #new up a concrete builder
      soccer_builder = SoccerFootballTeamBuilder.new

      #go again a second time with another builder
      aussie_rules_builder = AustralianRulesFootballTeamBuilder.new

      #go again a second time with another builder
      rugby_league_builder = RugbyLeagueFootballTeamBuilder.new

      #pass the bulders build to the Director
      f.build_football_team(soccer_builder)
      f.build_football_team(aussie_rules_builder)
      f.build_football_team(rugby_league_builder)

      #store the teams and details in arrays
      @team1 = [soccer_builder.footy_team?.team_type_name?,
        soccer_builder.print_team_details]
      @team2 = [aussie_rules_builder.footy_team?.team_type_name?,
        aussie_rules_builder.print_team_details]
      @team3 = [rugby_league_builder.footy_team?.team_type_name?,
        rugby_league_builder.print_team_details]

      self.listBox1.Items.Add(@team1[0])
      self.listBox1.Items.Add(@team2[0])
      self.listBox1.Items.Add(@team3[0])

end
ironruby_builder_ui
ironruby_builder_ide Used in concert with a Windows::Forms application (with some help from Ruby In Steel) we can build the following user interface to demonstrate our Builder(s) in action. The entire code can be found here and includes all the code and presentations from previous episodes in the series. Next in the series is the last of the creational patterns, the Prototype pattern.

Share/Save/Bookmark

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia