DPS907 notes – Thu Oct 1

A variety of topics today.

.

Review Tests 1 and 2

Before we have Test 3, the other tests (1 and 2) will be returned and discussed. The goal is to help you improve your answer quality.

Example answers will be posted after each test. On the class notes page, click any of the test links, to view the answer page.

.

Test 3 is today

Next, Test 3 will be written.

The topics on the test will cover this week’s theme (refactoring), but will NOT include any questions about Microsoft Azure Services.

.

More refactoring improvements

Recently, you learned how to refactor your code with an introduction to a repository pattern. The content that follows builds upon the introductory content from the last class.

We will trace several standard workflows, from the controller, which calls a method in the entity-specific repository, which calls a method in the repository abstract base class.

.

Implementing “get all”, no associated data

Let’s start at the Artists controller. It calls a method in the Artist repository.

public IHttpActionResult Get()
{
    return Ok(w.Artists.GetAll());
}

.

Look at the Artist repository. We have decided that it will return an ArtistBase collection. It calls a method in its base class. Notice that it passes null, which means that we do not want any associated data.

public IEnumerable<ArtistBase> GetAll()
{
    // Call the base class method
    var fetchedObjects = RGetAll(null);

    // Notice that we can do the sort here if we want to
    return Mapper.Map<IEnumerable<ArtistBase>>
        (fetchedObjects.OrderBy(a => a.ArtistName));
}

.

Look at the Repository abstract base class. The method works whether or not associated data is requested.

protected IEnumerable<T> RGetAll(string[] navProps)
{
    // Start building the query
    IQueryable<T> query = _dbset;

    // Continue building the query, if there are navigation properties
    if (navProps != null)
    {
        foreach (var navProp in navProps)
        {
            query = query.Include(navProp);
        }
    }

    // Execute the query, and return the results as IEnumerable<T>
    return query.AsEnumerable();
}

.

Implementing “get all”, WITH associated data

Let’s start at the Artists controller. It calls a method in the Artist repository.

[Route("api/artists/withmembers")]
public IHttpActionResult GetWithMembers()
{
    return Ok(w.Artists.GetAllWithMembers());
}

.

Look at the Artist repository. We have decided that it will return an ArtistSelf collection, which renders associated data.

It calls a method in its base class – the same method that was called by the “no associated data” example above.

Notice that it passes a string array that has the names of the navigation properties for the associated data.

public IEnumerable<ArtistSelf> GetAllWithMembers()
{
    // Call the base class method, ask for associated data
    var fetchedObjects = RGetAll(new[] { "Members" });

    return Mapper.Map<IEnumerable<ArtistSelf>>(fetchedObjects);
}

.

Implementing “get one”, no associated data

Let’s start at the Artists controller. It calls a method in the Artist repository.

public IHttpActionResult Get(int? id)
{
    // Fetch the object
    var fetchedObject = w.Artists.GetById(id.GetValueOrDefault());

    return (fetchedObject == null) 
    ? NotFound() 
    : (IHttpActionResult)Ok(fetchedObject);
}

.

Look at the Artist repository. We have decided that it will return an ArtistBase object. It calls a method in its base class. Notice that it passes null, which means that we do not want any associated data.

public ArtistBase GetById(int id)
{
    // Call the base class method
    var fetchedObject = RGetById(i => i.Id == id, null);

    return (fetchedObject == null) ? null : Mapper.Map<ArtistBase>(fetchedObject);
}

.

Look at the Repository abstract base class. The method works whether or not associated data is requested.

protected T RGetById(Expression<Func<T, bool>> predicate, string[] navProps)
{
    // Start building the query
    IQueryable<T> query = _dbset;

    // Continue building the query, if there are navigation properties
    if (navProps != null)
    {
        foreach (var navProp in navProps)
        {
            query = query.Include(navProp);
        }
    }

    // Execute the query, and return the results as IEnumerable<T>
    return query.SingleOrDefault(predicate);
}

.

Implementing “get one”, WITH associated data

Let’s start at the Artists controller. It calls a method in the Artist repository.

[Route("api/artists/{id}/withmembers")]
public IHttpActionResult GetWithMembers(int? id)
{
    // Fetch the object
    var fetchedObject = w.Artists.GetByIdWithMembers(id.GetValueOrDefault());

    return (fetchedObject == null) 
    ? NotFound() 
    : (IHttpActionResult)Ok(fetchedObject);
}

.

Look at the Artist repository. We have decided that it will return an ArtistSelf object, which renders associated data.

It calls a method in its base class – the same method that was called by the “no associated data” example above.

Notice that it passes a string array that has the names of the navigation properties for the associated data.

public ArtistSelf GetByIdWithMembers(int id)
{
    // Call the base class method, ask for associated data
    var fetchedObject = 
        RGetById(i => i.Id == id, new[] { "MemberOfArtist", "Members" });

    return (fetchedObject == null) ? null : Mapper.Map<ArtistSelf>(fetchedObject);
}

.

Getting started with Microsoft Azure Services

From Wikipedia:

“Microsoft Azure is a cloud computing platform and infrastructure, created by Microsoft, for building, deploying and managing applications and services through a global network of Microsoft-managed datacenters. It provides both PaaS and IaaS services and supports many different programming languages, tools and frameworks, including both Microsoft-specific and third-party software and systems.”

.

We will use Azure to host our web services. Every student (in the class) will receive a 6-month Microsoft Azure Academic Pass, at no cost. The Academic Pass enables you to consume up to $100 of services per month.

Follow this guide to get started with Azure.

.

Step 1 – Create a new Microsoft Account

Every Seneca student already has a “Microsoft Organizational Account”, which is simply the account with the “myseneca.ca” suffix.

It may also be possible that you also have a standard “Microsoft Account”, ending in “live.ca”, “hotmail.com”, or “outlook.com”.

Please do not use either of those accounts when you work with Azure.

Instead, create a new Microsoft Account. It is likely that the lifetime of this new account will be short, perhaps only for the duration of the course. That’s OK, and you can consider this to be a throw-away account.

Visit this page to create a new Microsoft Account: signup.live.com

Do you need a suggestion for an account name?

Your professor suggests using an account name that you like, with a suffix “-ws2015” (which could mean “web services in 2015”).

The Microsoft Account name is not publicly visible. You must use it when you login to the management portal, and when deploying an app from Visual Studio.

.

Step 2 – Redeem your Azure Academic Pass

Before continuing, ensure that your browser has signed out of all Microsoft services.

Visit this page to redeem your Azure Pass: microsoftazurepass.com

Complete the form, specifying “Canada” as the country, and the 14-character code that was provided to you in class.

Continue following the process. If you need help, read the “how to” information.

.

Step 3 – Create your first Web App and SQL database

For this course, we will use Microsoft Azure Web Apps and SQL databases.

In the next two months, you will create and use a small number of Web Apps. Your Azure Pass enables you to create up to ten (10) Web Apps. In addition, you can create up to two (2) database servers. However, each database server can hold one or more SQL databases.

The first app that you will deploy is Lab 3. The recommended name for your first web app will be a composite of your part of your College “myseneca.ca” account name, and a suffix “-ws2015lab3”.

For example, if your College “myseneca.ca” login name is ‘pmcintyr’, you will create a web app to host your labs, with this publicly-available Web App name:

pmcintyr-ws2015lab3.azurewebsites.net

The database server name will be auto-generated by Azure. However, we can choose the SQL database name. For your labs, the SQL database name will be:

Lab3Database

During the creation of the database server, you must create or define credentials. This is a normal task, and similar to your past experience with database servers. If you wish, you can use the same login name and password as your Microsoft Account.

Watch this video to learn how to complete these tasks.

.

Step 4 – Prepare your Lab 3 project

A general Azure rule: If your web app or web service uses a database, then you must use Code First Migrations.

You were first introduced to Migrations in your web apps programming course. The following content is repeated and adapted from the professor’s Winter 2015 coverage of the topic:

Migrations deliver two benefits to the programmer:

  1. It enables the app to keep its existing data when you make minor changes to your design model classes.
  2. It enables the deployment of your app to Azure

.

Configuring Migrations requires you to complete one or two simple tasks:

  1. Enable migrations
  2. After a change (or set of changes), add a ‘migration’ definition, and update the data store.

The first task is to “enable” Migrations. In Visual Studio, open the Package Manager Console.

Type the following command. It’s a once-per-project command. After you do this, you will not have to do it again for the current project:

enable-migrations

.

This command configures the base or start state of the design model classes, and its persistent store implementation.

If you not made any changes to your design model classes, then you can skip the second task below. Read the package manager console messages carefully – it will tell you the status.

Later, whenever you have made a change to your design model classes, you do the second task, by executing the following two commands in the Package Manager Console:

add-migration DescriptiveNameForTheMigrationDefinition
update-database

.

In a new (or almost new) project, the descriptive name for your first migration definition can be “Initial” or something similar.

If you anticipate performing many changes, then you can do the add-migration and update-database in a granular way. Or, you could just do all your changes, and run these commands once.

.

Step 5 – Deploy the Lab 3 project to Azure

In Visual Studio, right-click the project item in Solution Explorer, and select Publish.

 

.

Watch this video to learn how to deploy your Lab 3 web app to Azure.

Note: The video may include a discussion of a “virtual application”, and a publish target of “lab3”, etc. You can ignore that part of the video, as we have discovered that the use of a “virtual application” is not necessary.

.

.

.

.

.

.

.

.

.

.

.

.

.

%d bloggers like this: