Skip to main content

The scope of a PoC

Let us talk about what it should be the scope of a PoC and what you should or you should not have in a PoC.

Purpose of PoC
First, we need to define what is the purpose of a PoC is. The main purpose is to demonstrate the principles that are covered in technical documents (that it is not just theory and diagrams).

It is already a deja vu for me to hear people that they want to reuse the PoC output in the main project. This happens because many times the PoC scope is too big and does not covers only the ideas that needs to be demonstrated.
When you have a PoC that covers more than 15% of the implementation effort than you might have a problem. That is not a PoC anymore, it is a PILOT, that represents a system with a limited functionality that go in production. The Pilot might have many restrictions, from NFRs to business use cases that are covered, but it has some part that works.
You will never want to invest in a PoC more than it is necessary and you shall always push the output code to trash. Even if it is working code, it should never reach the Pilot or production. Yes, technical team might look over the PoC implementation to get inspiration, but nothing more than this.

It is so common to add to the PoC scope things that are general truth. A general truth is well documented already and proven by others.
A good example is to check in a PoC that Azure AD can be used as authentication mechanism inside an ASP.NET MVC application. You already know that it works and you will find plenty official documentation. Yes, maybe the team do not have experience with this, but this does not means that it will not work.

Challenge the PoC Scope
Let us take for example the following PoC scope:

  • Import data from a 3rd party provider
  • Store data inside CosmosDB
  • Validate data and move it to Azure SQL
  • Expose data inside a ASP.NET MVC application using OData
  • Use Azure AD for authentication in front of OData Service
  • Use data access restrictions to OData services based on user role
  • Create a simple web application based on Angular
  • Display data that was read from OData Service

What do you think; it is the scope of this PoC valid?
I personally would say that it is not. Most of the items included in PoC are general truth and you know that they will work. Let’s take a look one by one and see.
Import data from a 3rd party provider: This is a valid PoC item and it should be kept. Even if it is more on integration side, you want to validate that you can communicate and extract data from an external 3rd party.
Store data from 3rd party inside CosmosDB: You need to keep data somewhere, but what is the purpose of this inside the PoC. Taking into account the other items, the data is kept only to validate it and move it Azure SQL. In this case, the validation can be done on the fly and there is no need to keep it inside CosmosDB for PoC.
Validate data and move it to Azure SQL: The validation is a valid point to show how data transformation is done, but you need to cover only one data type. There is no need to cover all of them. You can keep the data inside Azure SQL for PoC, but a binary file should work as well. You demonstrate the validation part, not the storage. It is clear that you can store data inside Azure SQL.
Expose data inside an ASP.NET MVC application using OData: This can be added to the scope as long you expose only one entity and you want to validate that you can restrict access to data based on user role. Otherwise, OData can be used to offer access to entities. Another case when you would want to include OData inside PoC is when you have a complex data structure and you want to be sure that it is possible to expose only a part of it in the way that you want.
Use Azure AD for authentication in front of OData Service: If you would have only this inside PoC, this would be a general truth. Combined with the next requirement, it might make sense to include inside PoC. Even if, the next item can be seen as a general truth.
Use data access restrictions to OData services based on user role: We know that inside an ASP.NET MVC application you can restrict access based on user role. This is kind of general truth but let’s say that it might be included inside a PoC.
Create a simple web application based on AngularJS: What is the purpose of it? You can validate the authentication and role based using a simple C# code. There is no need to create an Angular application only for it. Only if you want to define the base template and in this case it is the pilot.
Display data that was read from OData Service inside AngularJS: As long as you don’t use a custom UI controller or things like this, this is pretty clear that will work and it doesn’t make sense to include it.

As we can see, most of the things that were included were general truth and you do not need to cover them inside a PoC.

PoC Optimization
There are some things that you can do to optimize the PoC. Even if you don’t plan to use EF, for the PoC it might be useful to extract data from SQL using EF. You can use the designer from database and you would not need to write a line of code. The same thing for OData. You can expose content that is read using EF, giving you the option to write 0 lines of code to read data from Azure SQL and expose as OData. This is applicable as long as you don't have in the scope some NFRs like performance on reading data from storage.

What you should remember

  • Focus inside PoC only on things that you need to prove that work. 
  • Do not validate inside a PoC things that you already know that are general truth.
  • Avoid defining the design of the application during PoC
  • Do not reuse PoC code in production


  1. I would say that sometimes just a better name should be found - very often, PoC means "opportunity to learn about some new technology".. :) So it is used as a time-boxed way to later answer questions like: "how long would _you_ need to complete that?" or "how hard is for _you_ to use that technology?" :)


Post a Comment

Popular posts from this blog

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

Entity Framework (EF) TransactionScope vs Database.BeginTransaction

In today blog post we will talk a little about a new feature that is available on EF6+ related to Transactions.
Until now, when we had to use transaction we used ‘TransactionScope’. It works great and I would say that is something that is now in our blood.
using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (SqlConnection conn = new SqlConnection("...")) { conn.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = conn; sqlCommand.CommandText = ... sqlCommand.ExecuteNonQuery(); ... } scope.Complete(); } Starting with EF6.0 we have a new way to work with transactions. The new approach is based on Database.BeginTransaction(), Database.Rollback(), Database.Commit(). Yes, no more TransactionScope.
In the followi…

GET call of REST API that contains '/'-slash character in the value of a parameter

Let’s assume that we have the following scenario: I have a public HTTP endpoint and I need to post some content using GET command. One of the parameters contains special characters like “\” and “/”. If the endpoint is an ApiController than you may have problems if you encode the parameter using the http encoder.
using (var httpClient = new HttpClient()) { httpClient.BaseAddress = baseUrl; Task<HttpResponseMessage> response = httpClient.GetAsync(string.Format("api/foo/{0}", "qwert/qwerqwer"))); response.Wait(); response.Result.EnsureSuccessStatusCode(); } One possible solution would be to encode the query parameter using UrlTokenEncode method of HttpServerUtility class and GetBytes method ofUTF8. In this way you would get the array of bytes of the parameter and encode them as a url token.
The following code show to you how you could write the encode and decode methods.