Angular JS – Constants

angular.module("myApp", [
    "myApp.constants",
    "myApp.controllers"
]);
angular.module("myApp.constants", []);
angular.module("myApp.controllers", []);
...
angular.module("myApp.constants").constant('constants', {
    STATUS_ID_LIVE: 3,
    STATUS_ID_PENDING: 2,
    STATUS_ID_CLOSE: 1
});
...
angular.module("myApp.controllers").controller("mainCtrl", ["$scope", "constants", function ($scope, constants) {
    $Scope.status = constants.STATUS_ID_CLOSE;
}]);
Advertisements

Angular JS – ngRepeat with TrackBy

With the TrackBy is possible to tell Angular how to recognize object within a collection to understand if, after an update, a particular index refers to the same updated object or to a new object. In this way Angular can avoid to destroy the DOM and re-create it each time, operating a more punctual update on element that are just changed in some field. This is better for performances and we don’t lose our markup bindings (e.g. the twitter post widget or the jQuery events) at each refresh.

<ul class="post-list">
    <li class="post {{ post.classNames }}" ng-repeat="post in blog.data.posts track by post.id">
        <post></post>
    </li>
</ul>

Automapper

With Automapper we can automatically perform deep copies between different object through reflection. The default mapping attempt to copy properties with the same name from the source type to the destination type. Is very useful when we want to generate to copy a model object to a view model object or to a subclassed object.

To perform a copy we have to map each involved source/destination type for our copy. In this case we are creating a mapping between the GlobalData and the SpecificData types to get a new SpecificData instance from a GlobalData instance.

Mapper.CreateMap<GlobalData, SpecificData>();
SpecificData dst = Mapper.Map<GlobalData, SpecificData>(src);

Using a custom Constructor

We can define as well more complex mappings. In this case we are instructing Automapper to use a particular constructor to create our MyFeedItem instances. As we can see from this example we can map a collection just by mapping its inner element’s type.

Mapper.CreateMap<OuterFeed, MyFeedItem>()
    .ConstructUsing((OuterFeed src) => new MyFeedItem(GlobalData));
var Feeds = Mapper.Map<IEnumerable<OuterFeed>, IEnumerable<MyFeedItem>>(feeds);

Mapping through Subclasses

If we need to map a type which includes some property of abstract/interface type we have to tell Automapper how to map each of its derived/concrete types. We can have the same situation even when we are working with subclassed object.

In this example we want to map a ItemModel type to a ItemViewModel type. The ItemModel type includes a property of type RelatedItemModel, that is an abstract class, so within an instance we’ll find one of its derived types: RelatedItemModelCountry, RelatedItemModelGender or RelatedItemModelGeneric.

On the other side, the ItemViewModel type includes a correspondent property of type RelatedItemViewModel, that is an abstract class as well, so within an instance we’ll find one of its derived types: RelatedItemViewModelCountry, RelatedItemViewModelGender or RelatedItemViewModelGeneric.

AutoMapper.Mapper.CreateMap<ItemModel, ItemViewModel>();
AutoMapper.Mapper.CreateMap<RelatedItemModel, RelatedItemViewModel>()
    .Include<RelatedItemModelCountry, RelatedItemViewModelCountry>()
    .Include<RelatedItemModelGender, RelatedItemViewModelGender>()
    .Include<RelatedItemModelGeneric, RelatedItemViewModelGeneric>();
AutoMapper.Mapper.CreateMap<RelatedItemModelCountry, RelatedItemViewModelCountry>();
AutoMapper.Mapper.CreateMap<RelatedItemModelGender, RelatedItemViewModelGender>();
AutoMapper.Mapper.CreateMap<RelatedItemModelGeneric, RelatedItemViewModelGeneric>();
var itemViewModel= AutoMapper.Mapper.Map<ItemModel, ItemViewModel>(item);

Setting up a TCP/IP connection

In this case we are using a TCP/IP connection to get XML feeds from a remote server.

public class FeedProvider : IFeedProvider, IDisposable
{
    private readonly IDataFeedConfig _config;
    private volatile bool _readingThreadStop;
 
    public event EventHandler<Message> Notify;
    public event EventHandler<FeedType2> FeedReceived;
 
    public FeedProvider(IDataFeedConfig config)
    {
        _config = config;
    }
 
    public void StartReceivingFeeds()
    {
        Notify(this, new Message(MessageType.MSG_FEED_PROVIDER_START_RECEIVING_FEEDS));
        var readingThread = new Thread(HandleReadingThread);
        _readingThreadStop = false;
        readingThread.Start();
    }
 
    public void StopReceivingFeeds()
    {
        Notify(this, new Message(MessageType.MSG_FEED_PROVIDER_STOP_RECEIVING_FEEDS));
        Dispose();
    }
 
    #region Private Methods
 
    private void HandleReadingThread()
    {
        const int UNKNOWN_ERR_MAX_COUNT = 10;
        const int TIMEOUT_DURATION = 10000;
 
        while (true)
        {
            lock (this)
            {
                if (_readingThreadStop) break;
            }
 
            var unknownErrCount = 0;
            string readStr = null;
            using (var client = new TcpClient())
            {
                try
                {
                    //Start the connection
                    Notify(this, new Message("Connecting to the Server"));
                    client.Client.SetSocketOption(SocketOptionLevel.Socket,
                        SocketOptionName.KeepAlive, true);
                    client.Connect(_config.Mf_HostName, _config.Mf_HostPort);
 
                    //The connection is open
                    Notify(this, new Message(MessageType.MSG_FEED_PROVIDER_CONNECTION_OPEN));
                    using (NetworkStream stream = client.GetStream())
                    {
                        stream.ReadTimeout = TIMEOUT_DURATION;
                        stream.WriteTimeout = TIMEOUT_DURATION;
                        using (var sr = new StreamReader(stream))
                        {
                            using (var sw = new StreamWriter(stream))
                            {
                                while (client.Connected)
                                {
                                    lock (this)
                                    {
                                        if (_readingThreadStop) break;
                                    }
 
                                    try
                                    {
                                        readStr = sr.ReadLine();
                                        XDocument doc = XDocument.Parse(readStr);
                                        IEnumerable<XDocument> response = ManageReceivedDoc(doc);
                                        foreach (XDocument responseDoc in response)
                                        {
                                            Notify(this, new Message(string.Format("Sending XML: {0}", responseDoc)));
                                            sw.WriteLine(responseDoc.ToString(SaveOptions.DisableFormatting));
                                            sw.Flush();
                                        }
                                        unknownErrCount = 0;
                                    }
 
                                    #region Error Management
 
                                    catch (XmlException)
                                    {
                                        Notify(this, new Message(string.Format("Received Invalid XML: {0}", readStr)));
                                    }
                                    catch (Exception e)
                                    {
                                        unknownErrCount++;
                                        Notify(this, new Message(string.Format("Unknown Error ({0} of {1}): {2}", unknownErrCount,
                                            UNKNOWN_ERR_MAX_COUNT, e.Message)));
                                        if (unknownErrCount == UNKNOWN_ERR_MAX_COUNT)
                                        {
                                            Notify(this, new Message("Too Many Unknown Errors. The Connection will be Closed"));
                                            break;
                                        }
                                    }
                                    #endregion
                                }
                            }
                        }
                    }
                }
 
                #region Error Management
 
                catch (SocketException e)
                {
                    Notify(this, new Message(string.Format("Cannot access to Server: {0}", e.Message)));
                }
                catch (Exception e)
                {
                    Notify(this, new Message(string.Format("Unknown Error: {0}", e.Message)));
                }
                #endregion
 
                if (client.Connected) client.Close();
                Notify(this, new Message(MessageType.MSG_FEED_PROVIDER_CONNECTION_CLOSED));
            }
 
            //Wait before reconnect
            Thread.Sleep(_config.ReconnectFrequency);
        }
        Notify(this, new Message("Thread Closed"));
    }

    private IEnumerable<XDocument> ManageReceivedDoc(XDocument doc)
    {
        var response = new List<XDocument>();
        switch (doc.Root.Name.LocalName)
        {
            case "FeedType1":
                var feedType1 = new FeedType1(doc);
                Notify(this, new Message(string.Format("Received FeedType1: {0}", feedType1)));
		
                //For this feed is provided a response
                AddSubscriptionsToResponse(response, feedType1);
                break;
 
            case "FeedType2":
                var feedType2 = new FeedType2(doc);
                Notify(this, new Message(string.Format("Received FeedType2: {0}", feedType2)));
                FeedReceived(this, feedType2 );
                break;
 
            default:
                Notify(this, new Message(string.Format("Received Unrecognized XML: {0}", doc)));
                break;
        }
        return response;
    }
 
    private void AddSubscriptionsToResponse(List<XDocument> response,
        FeedType1 feedType1)
    {
		response.Add(new ResponseMessage(feedType1).Doc);
    }
    #endregion
 
    public void Dispose()
    {
        lock (this)
        {
            _readingThreadStop = true;
        }
    }
}

Creating a Windows Service

https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx

After creating the project a Service class will be added to our project (we renamed it to MyWinService).

We can now open the designer for that class and add a Service Installer for our service by right-clicking and selecting the Add Installer option. A new ProjectInstaller class will be added to the project. We can configure it by opening the designer and setting the properties for its components (ServiceInstaller and ServiceProcessInstaller).

We can install the service using the installutil command from the VS Developer Command Prompt. To uninstall the service we can use the same command with the “/u” argument.

After the service has been installed we can start/stop it from the usual form we use to manage services. Once installed we don’t need to do any other operation. Of course before each rebuild we need to stop the service and restart it again after the rebuild has finished. We can’t rebuild while the service is running.

We can debug the process with the Attach To Process command from VS. Is often useful as well to write some log about what the process is doing. To do this we can use the EventLog object to write on the Windows Logs.

public partial class WinService : ServiceBase
{
    WindsorContainer container;
    IMyService service;
 
    public WinService()
    {
        InitializeComponent();
 
        //Creates Castle Container
        container = new WindsorContainer();
        container.Install(new CastleInstaller());
    }
 
    protected override void OnStart(string[] args)
    {
        //Resolves MyService
        service = container.Resolve<IMyService>();
        service.Notify += (sender, message) =>
        {
            EventLog.WriteEntry(message);
        };
        service.Start();
 
    }
 
    protected override void OnStop()
    {
        service.Stop();
 
        //Releases MyService
        container.Release(service);
    }
}

Debugging with a Console Application

To have a more easy debug a is good solution to create another project (e.g. a Console Application) that replicates the process’ logic. In this way we can use that application to debug and test our logic, instead of using Attach To Process/Windows Logs with the real process.

Integrating MVC with Castle.Windsor

To be able to use the DI within our MVC controllers we have to replace the default MVC Framework’s Controller Factory with a custom one that uses Castle.Windsor. First of all we have to create the new Controller Factory (e.g. within a folder named “Infrastructure”):

public class CastleControllerFactory : DefaultControllerFactory
{
    public IWindsorContainer Container { get; private set; }
 
    public CastleControllerFactory(IWindsorContainer container)
    {
        if (container != null)
        {
            Container = container;
        }
        else
        {
            throw new ArgumentNullException("container");
        }
    }
 
    protected override IController
        GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        //Resolves Controller
        if (controllerType != null)
        {
            return Container.Resolve(controllerType) as IController;
        }
        return null;
    }
 
    public override void ReleaseController(IController controller)
    {
        if (controller is IDisposable)
        {
            ((IDisposable)controller).Dispose();
        }
 
        //Releases Controller
        Container.Release(controller);
    }
}

Now we have to tell MVC Framework to use our Controller Factory instead of the default one. To do this we have to add some code to the Application_Start() method in the global.asax file:

void Application_Start(object sender, EventArgs e)
{
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
 
    //Creates Castle Container
    var container = new WindsorContainer();
    container.Install(new CastleInstaller());
 
    //Creates Castle Controller Factory (MVC)
    var castleControllerFactory = new CastleControllerFactory(container);
    ControllerBuilder.Current.SetControllerFactory(castleControllerFactory);
}

The CastleInstaller class is the usual class that we use to configure the mapping between each interface and its concrete class. We can create it within the same “Infrastructure” folder in which we created the Controller Factory.


Adding all the controllers to the installer

To have Castle working with our MVC application we should remember to register all the controllers within our CastleInstaller class. To avoid this (and to not have a too long configuration) we can automatically set the configuration of all the controllers via reflection. In this way any new controller will be found and properly added to Castle without writing any explicit line of code. Here is the code:

//Register all the MVC controllers
//in the current executing assembly
container.Register(Classes.FromThisAssembly().BasedOn<Controller>().LifestylePerWebRequest());

IoC and DI with Castle.Windsor

Castle.Windsor is the most complete and diffused IoC Container for .Net (is more powerful than Ninject).

To configure the IoC Container we have to specify the mapping between each interface and its concrete class. This can be done within a class which implements the IWindsorInstaller interface:

class CastleInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<IDependency1>().ImplementedBy<Dependency1>());
        container.Register(Component.For<IDependency2>().ImplementedBy<Dependency2>());
        container.Register(Component.For<IDependency3>().ImplementedBy<Dependency3>());
        container.Register(Component.For<IDependency4>().Instance(new Dependency()
        {
            Property1 = "Value1",
            Property2 = "Value2",
            Property3 = "Value3",
        }));
    }
}

After the configuration has been defined we can create the container and use it to resolve our instances. Castle will automatically resolve each dependency with the configured object:

static void Main(string[] args)
{
    //Creates Castle Container
    WindsorContainer container = new WindsorContainer();
    container.Install(new CastleInstaller());
 
    //Resolves MarshallFeed Service
    IMarshallFeedService service = container.Resolve<IMarshallFeedService>();
 
    ...
 
    //Releases MarshallFeed Service
    container.Release(service);
}

Automatically installing all the installer within an assembly

Instead of providing a specific instance of the installer to the container.Install() method (as in the example above) we can tell Castle to find all the installers within the assembly and to install them:

container.Install(FromAssembly.This());

Angular JS – Services

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Angular JS</title>
    <style>
        [ng-cloak],
        [data-ng-cloak],
        .ng-cloak {
            display: none !important;
        }
    </style>
</head>
<body>
    <div ng-app="myApp" ng-cloak>
        <div ng-controller="myController">
            <h1>Factory</h1>
            <p>The counter is {{ factory.counter }}</p>
            <button ng-click="factory.incrementCounter()">Increment counter</button>
            <br />
            <h1>Service</h1>
            <p>The counter is {{ service.counter }}</p>
            <button ng-click="service.incrementCounter()">Increment counter</button>
            <br />
            <h1>Provider</h1>
            <p>The counter is {{ provider.counter }}</p>
            <button ng-click="provider.incrementCounter()">Increment counter</button>
        </div>
    </div>
 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
 
    <script>
 
        //-----------------------------
        //Application Main
        //(should be in "/app/run.js")
        //-----------------------------
 
        angular.module("myApp", ["myApp.controllers", "myApp.services"]).config(
            ["myCounterProviderProvider", function (myCounterProviderProvider) {
 
                //To refer the myCounterProvider provider
                //here we have to add the "Provider" suffix
                myCounterProviderProvider.incrementSize = 3;
            }]);
        angular.module("myApp.controllers", []);
        angular.module("myApp.services", []);



        //------------------------------------------------------
        //Application Controllers
        //(should be in "/app/controllers/<controllerName>.js")
        //------------------------------------------------------
 
        angular.module("myApp.controllers").controller("myController",
            ["$scope", "myCounterFactory", "myCounterService", "myCounterProvider",
            function ($scope, myCounterFactory, myCounterService, myCounterProvider) {
                $scope.factory = myCounterFactory;
                $scope.service = myCounterService;
                $scope.provider = myCounterProvider;
            }]);



        //------------------------------------------------
        //Application services
        //(Should be in "/app/services/<serviceName>.js")
        //------------------------------------------------
 
        /*
        Services are singleton objects shared between all the application's controllers.
        They can be required as dependencies by each module in the same way they require
        the $scope or the $http objects (they are dependencies as well). Angular use his
        dependancy injection system to provide them.
        */
 
        /*
        Factory services return an object
        */
        angular.module("myApp.services").factory("myCounterFactory", [function () {
            return new function () {
                var self = this;
 
                self.counter = 0;
                self.incrementCounter = function () {
                    self.counter++;
                };
            };
        }]);
 
        /*
        Service services define an object
        */
        angular.module("myApp.services").service("myCounterService", [function () {
            var self = this;
 
            self.counter = 0;
            self.incrementCounter = function () {
                self.counter++;
            };
        }]);
 
        /*
        Provider services are the most complex service type. The other types are derived
        from this one. Requiring modules will not receive, as dependancy, the whole provider
        object, but just the $get() method's result. The whole object will be accessible to
        the app.config() method, from where is possible to configure the provider's behavior
        (we need to add the "Provider" suffix to the provider's name). Providers are the
        only service type which can be referred by the app.config() method.
        */
        angular.module("myApp.services").provider("myCounterProvider", [function () {
            var self = this;
            self.incrementSize = 1;
 
            self.$get = function () {
                return new function () {
                    var self2 = this;
 
                    self2.counter = 0;
                    self2.incrementCounter = function () {
                        self2.counter += self.incrementSize;
                    };
                };
            };
        }]);
    </script>
</body>
</html>

Using cookies without JQuery

Sometimes is necessary to be able to access cookies (read/write) from vanilla Javascript. For example if we are using JQuery 2.0, that doesn’t support IE8, but we need to manage some behavior for the other browsers, such as a message that warn the user about using an obsolete browser and that needs a cookie to not be displayed after the user pressed OK.

function ie8_setCookie(name, value, days) {
    var expires;
    if (days) {
        var date = new Date();
        date.setDate(date.getDate() + days);
        expires = ";expires=" + date.toGMTString();
    }
    else {
        expires = "";
    }
    document.cookie = name + "=" + escape(value) + expires + ";path=/";
}
 
function ie8_getCookie(name) {
    var i, x, y, cookies = document.cookie.split(";");
    for (i = 0; i < cookies.length; i++) {
        x = cookies[i].substr(0, cookies[i].indexOf("="));
        y = cookies[i].substr(cookies[i].indexOf("=") + 1);
        x = x.replace(/^\s+|\s+$/g, "");
        if (x == name) {
            return unescape(y);
        }
    }
    return null;
}

Angular JS – Setting a behaviour for a Custom Directive

I can use the link property to set a particular behavior (instead of/along with a template) for a directive. In this example i define the ng-enter directive to handle the pression of the return button in a text box. Within the link function I can use JQuery (is a lite version provided by Angular itself) to define the behavior associated with the directive.

angular.module('angularApp.directives').directive('ngEnter', function () {
    return {
        restrict: "A",
        link: function ($scope, element, attributes) {
            element.bind("keydown keypress", function (event) {
                if (event.which === 13) {
                    $scope.$apply(function () {
                        $scope.$eval(attributes.ngEnter, { 'event': event });
                    });
                    event.preventDefault();
                }
            });
        }
    }
});

And this is the directive usage:

<input class="search-text" type="text" data-ng-model="searchText" data-ng-enter="Search()" placeholder="Search" />