Kurser och utbildning av IT-proffs och systemutvecklare

i Sök

Cornerstones utvecklarblogg

Alla Taggar

All Tags » .Net   (RSS)

  • .NET 4.0 is to Lazy

    With .NET 4.0 there is a new class added to the System namespace called Lazy<T>. This class is what the name applies, lazy. Here is an example where Lazy is used:

    var lazy = new Lazy(IList<OrderRow>>(
                                    () =>
                                    {
                                            var rows = //get order rows;
                                            return rows;
                                    });
    
    var rows = lazy.Value;
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    The Lazy<T>’s constructor can take a Func<T> as an argument, the function passed as an argument to the contractor will first be invoked when the Value property of the Lazy<T> class is used, but not invoked the next time the Value property is used. The code above will first execute the function passed as an argument when the we request the value of the Lazy<T>, the returned value of the function will be cached. The next time Value is used, the function will not be invoked, instead the cached value will be returned. This class  can for example be used when we want some kind of Lazy Loading.

    I’m on twitter: http://www.twitter.com/fredrikn

  • How SubmitChanges works in .NET RIA Servies

    Now I’m back from my 4 week long vacation. I have spend a lot of time with my new apartment, took about 2 month to get most of it ready, I still have a lot of things to do, but all the painting and stuff are done :) I got a question on my e-mail regarding .NET RIA Services and the Business Application project’s UserRegistartionService. It was about the AddUser method in the Service and when and where it’s called. I thought it would be great to write a post about it.

    Something that is good to have in mind is that the .NET RIA Services is all about code generation. The Business layer we are creating by following the .NET RIA Service business layer pattern and guide lines, will be used to generate proxy classes on the client-side to help us communicate to the server in a easy way. The proxy class on the client-side will use “Unit of Work” and Track changing etc. To use those features in a proper way, we have to use a specific “pattern” when we write our Business logic layer.

    Note: This post is based on the July Preview of the .NET RIA Services, and I also assume you have some basic knowledge about the .Net RIA Services.

    I will start with a custom DomainSerivce and how it works. Here is an example of a custom DomainService:

    [EnableClientAccess()]
    public class MyDomainService : DomainService
    {
    private List<Customer> _customers = new List<Customer>()
    {
    new Customer() { ID = 1, Name = "John Doe" },
    new Customer() { ID = 2, Name = "Jane Doe" }
    };

    public IEnumerable<Customer> GetCustomers()
    {
    return _customers;
    }


    public void AddCustomer(Customer customer)
    {
    _customers.Add(customer);
    }


    public void DeleteCustomer(Customer customer)
    {
    _customers.Remove( _customers.Find(c => c.ID == customer.ID));
    }


    public void UpdateCustomer(Customer customer)
    {
    var customerToUpdate = _customers.Find(c => c.ID == customer.ID);
    customerToUpdate = customer;
    }

    }


    public class Customer
    {
    [Key]
    public int ID { get; set; }

    public string Name { get; set; }
    }

    The code has a MyDomainService class and a Customer entity with two properties, ID and Name. The MyDomainService has four methods, GetCustomers, AddCustomer, DeleteCustomer and UpdateCustomer. When we build the code, the .NET RIA Services will generate our proxy classes (DomainContext) to help use communicate to the DomainService on the server-side. The generated proxy class will be add to our client project.

    Here is the generated proxy classes (I have removed some code to make it smaller):

     
    public sealed partial class Customer : Entity
    {

    private int _id;

    private string _name;

    public Customer()
    {
    ...
    }

    [DataMember()]
    [Key()]
    public int ID
    {
    get
    {
    return this._id;
    }
    set
    {
    ...
    this._id = value;
    ...
    }
    }

    [DataMember()]
    public string Name
    {
    get
    {
    return this._name;
    }
    set
    {
    ...
    this._name = value;
    ...
    }
    }

    public override object GetIdentity()
    {
    return this._id;
    }
    }

    public sealed partial class MyDomainContext : DomainContext
    {
    ...

    public EntityList<Customer> Customers
    {
    get
    {
    return base.Entities.GetEntityList<Customer>();
    }
    }

    public EntityQuery<Customer> GetCustomersQuery()
    {
    return base.CreateQuery<Customer>("GetCustomers", null, false, true);
    }

    ...
    }

    Note: The code I have removed is not important for this blog post.
     
    If you look at the generated code, you can see the Customer entity and a class with the name MyDomainContext. The MyDomainContext is the class that will communicate to our MyDomainService. As you can see, there is only two public members generated, Customers and GetCustomerQuery. The GetCustomer, AddCustomer, DeleteCustomer and UpdateCustomer are not added to the MyDomainContext class. So how can we call the Add-,Delete- and UpdateCustomer from the generated proxy class?
     
    As I mentioned before the.NET RIA Services have a track changing and an “Unit of Work” feature. The MyDomainContext class will have a method called SubmitChanges, which we can use to submit all changes, like updating entities, removing and adding etc. We can’t call the Add-, Delete- or UpdateCustomer method from the client-side directly, we must use the DomainContext “Unit or Work” feature.
     
    The Add, Delete and Update methods in the DomainService is needed if we want to be able to add, update or remove an entity. If we don’t add those methods to the DomainService, we aren’t allowed to Add, Delete or Update Entities on the client-side. So how can we call the Add, Update and Remove methods from the client-side by using the DomainContext’s Unit of Work.The following is an example:
     

    public partial class MainPage : UserControl
    {
    MyDomainContext _myDomainContext = new MyDomainContext();


    public MainPage()
    {
    var loadOperation = _myDomainContext.Load<Customer>(_myDomainContext.GetCustomersQuery());
    loadOperation.Completed += new EventHandler(loadOperation_Completed);

    }



    void loadOperation_Completed(object sender, EventArgs e)
    {
    var lastCustomer = _myDomainContext.Customers.Last();


     


     

    lastCustomer.Name = "Last Doe";



    _myDomainContext.Customers.Add(new Customer() { ID = 3, Name = "Jones Doe" });



    _myDomainContext.Customers.Remove(_myDomainContext.Customers.First());


    _myDomainContext.SubmitChanges();
    }


    In the constructor of the MainPage, the Load method of the MyDomainContext class is used. Because our generated DomainContext proxy inherits from the DomainContext base class, we have access to some methods, for example the Load and SubmitChanges method. The Load method will make an async call to the MyDomainSerivice’s GetCustomers method. When the DomainContext gets the results from the server, the loadOperation_Completed event will be “executed”. By using the MyDomainContext’s Customers property (generated by .Net RIA Services) we will have access to all the Customers that are loaded. The Customers property returns a EntitList. A DomainContext has an Entity Container, where all entities are stored. A Entity Container managed a set of EntityLists and have the responsibility to handle the changing tracking and identity management on the client.

    In the code above you can see that the Name of the last customer is set to “Last Doe”. When we update an Entity, an Update operation is added to the DomainContext’s “Unit of Work”, handled by the Entity Container. No updates will take place until we tell the Entity Container to process all of the changes. The code above will also call the Add and Remove method of the Customers property. When doing so, an Add and Remove operation is added to the list of work that should be processed when we call the SubmitChanges. When the SubmitChanges is called the changes are all sent to the service all together.

    Note: When we call the Add and Remove method etc, no calls to the server will take place. It will only take place when we call the SubmitChanges.

    So when the SubmitChanges is called, the DomainCotnext Unit of Work will be handled. We have Updated a Entity, added an Entity and also Removed and Entity. So the SubmitChanges will now do an async. call to the DomainService, and call the methods that will handle the operations, in this case the MyDomainService’s AddCustomer, RemoveCustomer and UpdateCustomer method will be executed on the server-side.

    There is a naming convention which can be used for the CRUD methods, here is a list form the .NET RIA Services documentation:

    Insert

        “Insert”, “Add”, “Create” prefixes
        Method signature : void InsertX(T entity), where T is an entity Type

    Update

        “Update”, “Change”, “Modify” prefixes
        Method signature : void UpdateX(T current), where T is an entity Type

    Delete

        “Delete”, “Remove” prefixes
       Method signature : void DeleteX(T entity), where T is an entity Type

    Query

        Method signature returning a singleton, IEnumerable<T> , IQueryable<T> where T is an entity Type, and taking zero or more parameters

    Resolve

       “Resolve” prefix
       Method signature : bool ResolveX(T curr, T original, T store, bool isDelete) where T is an entity type

    We can also use attributes (InsertAttribute/UpdateAttribute/DeleteAttribute/QueryAttribute/ResolveAttribute) if we don’t want to use the “reserved” words:


    [Delete]
    public void DestoryCustomer(Customer customer)
    {
    _customers.Remove( _customers.Find(c => c.ID == customer.ID));
    }

    Now when you know why some methods added to a Service isn’t available on the Client-side, we can go on with the Business Application project template’s UserRegistartionService

    If we take a look at the Business Application project template’s UserRegistartionService. We have the following methods:

    [EnableClientAccess]
    public class UserRegistrationService : DomainService
    {
    public void AddUser(UserInformation user)
    {
    MembershipCreateStatus createStatus;

    Membership.CreateUser(user.UserName, user.Password, user.Email, user.Question, user.Answer, true, null, out createStatus);
    if (createStatus != MembershipCreateStatus.Success)
    {
    throw new DomainServiceException(ErrorCodeToString(createStatus));
    }
    }

    public IEnumerable<UserInformation> GetUsers()
    {
    return null;
    }
    }

    We can’t from the client-side call the AddUser method, is not added to the UserRegistartionContext class. To add a new user we must add it to an EntityList, in this case the generated DomainContext will have a EntityList called UserInformations. This is generated out from the GetUsers query method. If we don’t have a query method, there is no way we can have access to an EntityList.
     
    In the Business Application template’s LoginWindow.xaml.cs file, the generated DomainContext is created in the constructor:
     
    private UserInformation _userInformation = new UserInformation();
    private UserRegistrationContext _registration = new UserRegistrationContext();

    public LoginWindow()
    {
    ...

    this._registration.UserInformations.Add(this._userInformation);
    this.registerForm.CurrentItem = this._userInformation;
    }

    As you can see, a new instance of the UserInformation entity (_userInformation) is added to the UserRegistartionContext’s UserInformations EntityList. At this case an Add operation is added to the UserRegistartionContext’s “Unit of Work”. The _userInformation is then bounded to a DataForm, which uses a two-way binding. So every changed done to the DataForm, will be done to the _userInformation object. When the Register button of the LoginWindow.xamls is called, the UserRegistrationService’s SubmitChanges method will be called, which will make sure the AddUser method of the UserRegistartionService will be executed and the _userInformation object will be passed as an argument to the AddUser method.

     

    private void RegisterButton_Click(object sender, RoutedEventArgs e)
    {
    ...

    _regOp = _registration.SubmitChanges();

    ...
    }

    I hope this post gave you some understanding about how the DomainContext and DomainSerice handle the CRUD methods etc.
  • Visual Studio 2008, Nya WCF och WF kurser, två WOW upplevelser!

    Wow, Wow, Wow. Det är min första spontana reaktion efter att ha ägnat en hel del tid åt att gå igenom två av Microsofts kurser från deras nya generation, den för Windows Communication Foundation och den för Läs mer...
  • Remove code smell with AOP

    During the last years you have probably heard about Aspect Oriented Programming (AOP). Different people like or don’t like AOP. I’m one of them who like AOP. As you may now VB.Net and C# are object orientated languages and with object oriented programming (OOP) you want to reduce code duplication, code duplications smells badly. If you need to do code duplication you are probably doing something wrong with the implementation of your domain model. With OOP you can generally eliminating code duplication, but there are some cases where we can’t avoid it, for example take a look at this code:

    public class MyClass
    {

           public void MyBusinessMethod1()
           {
                 CheckSecurity();
                 //Place your code here
           } 

           public void MyBusinessMethod2()
           {
                 CheckSecurity ();

                 //Place your code here
           } 

           public void CheckSecurity ()
           {
                //Place the code for the security check here
           }
    }

    The code above has code duplications, where CheckSecurity method is added to each business method. This code duplication is not only painful to write, it could also make the code smell bad and make the code less maintainable. With the refactoring Move Method "A method is, or will be, using or used by more features of another class than the class on which it is defined", the CheckSecurity method could be moved into the infrastructure and the new class where the method is located will be the only place where the CheckSecurity is located. Centralization of code will make it easier to maintain the code. Even if you use the Move Method, the MyClass still use code duplication. Unfortunately, OO doesn’t help us removing the code duplication. You could of course use code generation to manually avoid adding the CheckSecurity to each method where the security check needs to be done.

    AOP crosscutting can be used to address concerns such as the security checks and of course other application specific concerns too, for example, you could make Lazy Load work without needing to have a dependency to your Repository or data mapper within the domain objects. With AOP, you could remove the code duplication from the code example above, and create a method interceptor where you add the CheckSecurity method. The following is a pseudo code of an interceptor:

    public class MySecuirtyInterceptor : MethodInterceptor
    {
          public object Invoke(MethodInvocation invocation)
          {
                CheckSecurity (); 

                //Call next interceptor
                Return invocation.Proceed();
          }
    }

    By using an AOP framework where you could define a set of methods (pointcuts) that should use the security interceptor, you could easy remove the code duplication, and remove the security concern from the developer, and add it later, if it’s required. The The MyClass in the first example could look like this if we use AOP and the MySecurityInterceptor above:

    public class MyClass
    {
           public void MyBusinessMethos1()
           {
                 //Place your code here
           }

           public void MyBusinessMethos2()
           {
                 //Place your code here
           }
    }

    Developers don’t need to add the CheckSecurity method. If we need to have a security check before executing the method, you could add a pointcut later for the methods that should call the CheckSecurity. Some sophisticated AOP frameworks can use regular expression or other wildcard syntax for the pointcuts. Pointcuts is a set of Method, Fields or Throws (When a particular exception is thrown) that should invoke the interceptor method. Those pointcuts could for example be specified within a XML file.

    You can also use AOP to do some logging or other operations before or after a method has bean invoked, or a field has been set, or even when en exception was thrown. The developer who are creating the business methods, don’t need to call a method that will for example log a message, it’s something that could be specified within an XML file. By using AOP you could solve problems that could not be done with OOP. You can not only reduce the smell of bad code, you could also reduce time it takes to add the duplication of codes etc. I hope this post gave you some more information about how you can use AOP to solve some problems that can’t be easily done with OOP.


Den här bloggen

Syndication