In this post I want to discuss about our new functionality that allows to send perfect video bug reports(user feedback) from windows phone devices directly into your company bug tracker or test management system.

This came to reality with latest updates from Microsoft for their windows phone 8.1 devices.

We provide very simple API to integrate Bugrius into your mobile applications under windows phone 8.1.

You can send us a request at supportATbugrius.com and we will send you a guide how to get our new dot net SDK.

First off, let me remind you about our latest features and usage cases that we described on our web page here

And how you could hear previously that better one time to see than one hundred times to listen, we are starting :)

First of all, you need to add our mobile reference to your project.

reference

After you have added the assembly you can start to invoke our API directly from your mobile application.

To start recording a feedback you need to call StartRecording method (click to enlarge)

StartRecording

To stop recording invoke StopRecording method

StopRecording

Also you will need to use two objects: StateObject and BugReportMobile.

State object

You can use StateObject to receive recording status to show some progress bar on UI and to use recorded file name in your custom workflow.

Status of the operation is changed when StopRecording method is invoked and the recorded file is sent to Bugrius.

BugReport

If you have a look at the BugReportMobile object you can see required properties to be filled out when you put the object as a parameter to StartRecording method.

All these fields are custom and you can grab values from according UI elements of your application.

You can see the uploaded video bug report from our test application here.

If you will have any questions or suggestions please don’t hesitate to contact me.

Read more about Bugrius in my previous post.

Let me remind you that we have some programs for MVPs!

Follow us on Twitter, Facebook and join us in LinkedIn
Tagged with:  
Hi folks,
I’m glad to announce that you can get FREE Bugrius license if you will register at www.bugrius.com and send an e-mail to supportATbugrius.com specifying MVP in a subject of the e-mail.
You can read about Bugrius here and there.
If you are interested in the opportunity to send/receive video bug reports from windows phone 8.1 devices directly into your bug tracker please specify it in the e-mail as well.

Follow us on Twitter, Facebook and join us in LinkedIn

logo
Tagged with:  

Everyone faced with the situation when you deploy new version of software to a customer and starting to get tons of questions and claims regarding the software and many of these claims are needed to be described or discussed directly with the customer.  It consumes a lot of your time and that most important a lot of your nerve cells :)


Of course, you can ask your customer to send an e-mail with detailed description of what went wrong with attached screenshots and so on but it’s really painful and time consuming process for your customer.


And even if your customer is really IT skilled (because you need to have skills to make screenshots and write step by step instruction of what you did) often it doesn’t lead to the right direction. You need to call your customer, make some remote sessions to understand exactly what went wrong.


But even after all these steps the challenge is not completed because you need to create a case in your bug tracker system, assign it to correspondent developers and so on…


That’s why we created Bugrius!



Let users to spot and report bugs with a clear video report


You don’t need to ask them to send tons of screenshots or to write long step-by-step re-pro for an occasional bug – let them create clear video report with voice comments and share it in 1 click through integrated and free for you cloud storage.

Use your time on the phone for meaningful conversations, but not “now click here, move pointer to the right, etc.”


Get all the data you need from a short video report with voice commentary, not an hour long phone conversation with a user.

Save time and nerves on setting up screen sharing software or complicated (for users of course) online meeting tools.

Follow up with users and let them track bug fixes without never-ending email ping-pong


The users can see a status of the case and receive automatic email notifications if the status was changed.

Users can add feedback to an earlier closed case so you won’t need to start from scratch.

Have a bug tracker already? Just make it even more effective with simple integration of video reports


Trackers supported FogBugz, TFS and Jira (more coming soon).

Follow your own established workflow while getting clear video reports right in your favorite bug tracker.

Change bug tracker systems on the fly if needed.

And how I mentioned above we have seamless integration with most popular bug tracker systems such as TFS, Jira and FogBugz. The case created in one of the described bug tracker contains a tag (to understand from which customer the case was arrived), a full step records history to make the work with case more comfortable inside your bug tracker and of course the link by clicking on which you can view the video bug report with sound commentary from your customer.


 Just enjoy a movie :)


 Have a look at how it works or just jump into a free trial here.


P.S. Below you can see how the case created with Bugrius looks in Jira and TFS.

Jira (click to enlarge):

JIRA View

 

TFS (click to enlarge):

TFS View

 
Tagged with:  

Everyone thoroughly familiar with how to create a web site using IIS.  Also, many of you already known how to create Tree data structures in UI. I mean that data should be invoked only when we want to get dig into some node and click on ‘+’ sign to open the node structure.  And only then data should be invoked and shown.

Now I want to tell you a little excerpt from my today’s simple task.  There is some web site which is placed under some directory on HDD. In that directory there are many catalogs and one of them contains huge amount of small files in total size ~5 GBs (it’s not a good idea by the way). Ok, it’s not a problem to deploy such web site on IIS.

After the site was deployed on IIS, I decided to open root site directory but the whole IIS manager didn’t respond to any commands. Little bit strange I thought.  And that behavior appeared to me any time when I wanted to expand the root node of my site. Very strange.

I thought that a problem was with the directory contains many small files mentioned above. I removed that catalog and every thing works fine now.

The amazing thing is that that IIS manager tries to read information about underlying data structure of the site before it will be shown and doesn’t matter do you want to expand a node with huge amount of small files or not.  Seriously guys, fix it please.  

 

While working on some of my projects I use TransactionScope object from System.Transactions assembly. And I decided to see what kind of implementation the Dispose() method of the object has. 


I have no any words to describe it. 


   1:  public void Dispose()
   2:  {
   3:      bool flag = false;
   4:      if (DiagnosticTrace.Verbose)
   5:      {
   6:          MethodEnteredTraceRecord.Trace(SR.GetString("TraceSourceBase"), "TransactionScope.Dispose");
   7:      }
   8:      if (this.disposed)
   9:      {
  10:          if (DiagnosticTrace.Verbose)
  11:          {
  12:              MethodExitedTraceRecord.Trace(SR.GetString("TraceSourceBase"), "TransactionScope.Dispose");
  13:          }
  14:      }
  15:      else
  16:      {
  17:          if (this.scopeThread != Thread.CurrentThread)
  18:          {
  19:              if (DiagnosticTrace.Error)
  20:              {
  21:                  InvalidOperationExceptionTraceRecord.Trace(SR.GetString("TraceSourceBase"), SR.GetString("InvalidScopeThread"));
  22:              }
  23:              throw new InvalidOperationException(SR.GetString("InvalidScopeThread"));
  24:          }
  25:          Exception exception = null;
  26:          try
  27:          {
  28:              this.disposed = true;
  29:              TransactionScope currentScope = this.threadContextData.CurrentScope;
  30:              Transaction contextTransaction = null;
  31:              Transaction transaction = Transaction.FastGetTransaction(currentScope, this.threadContextData, out contextTransaction);
  32:              if (!this.Equals(currentScope))
  33:              {
  34:                  if (currentScope == null)
  35:                  {
  36:                      Transaction committableTransaction = this.committableTransaction;
  37:                      if (committableTransaction == null)
  38:                      {
  39:                          committableTransaction = this.dependentTransaction;
  40:                      }
  41:                      committableTransaction.Rollback();
  42:                      flag = true;
  43:                      throw TransactionException.CreateInvalidOperationException(SR.GetString("TraceSourceBase"), SR.GetString("TransactionScopeInvalidNesting"), null);
  44:                  }
  45:                  if ((currentScope.interopOption == EnterpriseServicesInteropOption.None) && (((null != currentScope.expectedCurrent) && !currentScope.expectedCurrent.Equals(transaction)) || ((null != transaction) && (null == currentScope.expectedCurrent))))
  46:                  {
  47:                      if (DiagnosticTrace.Warning)
  48:                      {
  49:                          TransactionTraceIdentifier transactionTraceId;
  50:                          TransactionTraceIdentifier empty;
  51:                          if (null == transaction)
  52:                          {
  53:                              empty = TransactionTraceIdentifier.Empty;
  54:                          }
  55:                          else
  56:                          {
  57:                              empty = transaction.TransactionTraceId;
  58:                          }
  59:                          if (null == this.expectedCurrent)
  60:                          {
  61:                              transactionTraceId = TransactionTraceIdentifier.Empty;
  62:                          }
  63:                          else
  64:                          {
  65:                              transactionTraceId = this.expectedCurrent.TransactionTraceId;
  66:                          }
  67:                          TransactionScopeCurrentChangedTraceRecord.Trace(SR.GetString("TraceSourceBase"), transactionTraceId, empty);
  68:                      }
  69:                      exception = TransactionException.CreateInvalidOperationException(SR.GetString("TraceSourceBase"), SR.GetString("TransactionScopeIncorrectCurrent"), null);
  70:                      if (null != transaction)
  71:                      {
  72:                          try
  73:                          {
  74:                              transaction.Rollback();
  75:                          }
  76:                          catch (TransactionException)
  77:                          {
  78:                          }
  79:                          catch (ObjectDisposedException)
  80:                          {
  81:                          }
  82:                      }
  83:                  }
  84:                  while (!this.Equals(currentScope))
  85:                  {
  86:                      if (exception == null)
  87:                      {
  88:                          exception = TransactionException.CreateInvalidOperationException(SR.GetString("TraceSourceBase"), SR.GetString("TransactionScopeInvalidNesting"), null);
  89:                      }
  90:                      if (DiagnosticTrace.Warning)
  91:                      {
  92:                          if (null == currentScope.expectedCurrent)
  93:                          {
  94:                              TransactionScopeNestedIncorrectlyTraceRecord.Trace(SR.GetString("TraceSourceBase"), TransactionTraceIdentifier.Empty);
  95:                          }
  96:                          else
  97:                          {
  98:                              TransactionScopeNestedIncorrectlyTraceRecord.Trace(SR.GetString("TraceSourceBase"), currentScope.expectedCurrent.TransactionTraceId);
  99:                          }
 100:                      }
 101:                      currentScope.complete = false;
 102:                      try
 103:                      {
 104:                          currentScope.InternalDispose();
 105:                      }
 106:                      catch (TransactionException)
 107:                      {
 108:                      }
 109:                      currentScope = this.threadContextData.CurrentScope;
 110:                      this.complete = false;
 111:                  }
 112:              }
 113:              else if ((this.interopOption == EnterpriseServicesInteropOption.None) && (((null != this.expectedCurrent) && !this.expectedCurrent.Equals(transaction)) || ((null != transaction) && (null == this.expectedCurrent))))
 114:              {
 115:                  if (DiagnosticTrace.Warning)
 116:                  {
 117:                      TransactionTraceIdentifier identifier;
 118:                      TransactionTraceIdentifier identifier2;
 119:                      if (null == transaction)
 120:                      {
 121:                          identifier2 = TransactionTraceIdentifier.Empty;
 122:                      }
 123:                      else
 124:                      {
 125:                          identifier2 = transaction.TransactionTraceId;
 126:                      }
 127:                      if (null == this.expectedCurrent)
 128:                      {
 129:                          identifier = TransactionTraceIdentifier.Empty;
 130:                      }
 131:                      else
 132:                      {
 133:                          identifier = this.expectedCurrent.TransactionTraceId;
 134:                      }
 135:                      TransactionScopeCurrentChangedTraceRecord.Trace(SR.GetString("TraceSourceBase"), identifier, identifier2);
 136:                  }
 137:                  if (exception == null)
 138:                  {
 139:                      exception = TransactionException.CreateInvalidOperationException(SR.GetString("TraceSourceBase"), SR.GetString("TransactionScopeIncorrectCurrent"), null);
 140:                  }
 141:                  if (null != transaction)
 142:                  {
 143:                      try
 144:                      {
 145:                          transaction.Rollback();
 146:                      }
 147:                      catch (TransactionException)
 148:                      {
 149:                      }
 150:                      catch (ObjectDisposedException)
 151:                      {
 152:                      }
 153:                  }
 154:                  this.complete = false;
 155:              }
 156:              flag = true;
 157:          }
 158:          finally
 159:          {
 160:              if (!flag)
 161:              {
 162:                  this.PopScope();
 163:              }
 164:          }
 165:          this.InternalDispose();
 166:          if (exception != null)
 167:          {
 168:              throw exception;
 169:          }
 170:          if (DiagnosticTrace.Verbose)
 171:          {
 172:              MethodExitedTraceRecord.Trace(SR.GetString("TraceSourceBase"), "TransactionScope.Dispose");
 173:          }
 174:      }
 175:  }
 

 


A while back, on the one of my projects I faced with a problem how to configure our custom framework to use specific data access technologies relying on connection string specified in app config of the project is intended to use the framework.


It’s a quite simple operation and can be realized using Factory design pattern.  And it’s not a point of this topic.


To overcome the problem I chose the solution based on using a simple enum and extension method. Let me show it.


 The needed enum type:


 public enum DatabaseType


    {


        SQLServer,


        MSAccess,


        Oracle


    }


 Extension method for DatabaseType:


 internal class ConfigurationObject


    {


        public IQueries QueryType { get; set; }


        public IDbInfrastructure DbInfrastructure { get; set; }


    }


     internal static class DbConfigurationExtension


    {


        internal static ConfigurationObject GetConfiguration(this DatabaseType type)


        {


            var sqlConfigObject = new ConfigurationObject { DbInfrastructure = new SqlDbInfrastructure(), QueryType = new MsSqlQueries() };


 


            switch (type)


            {


                case DatabaseType.SQLServer:


                    return sqlConfigObject;


                case DatabaseType.MSAccess:


                    return new ConfigurationObject{DbInfrastructure = new AccessDbInfrastructure(), QueryType = new AccessSqlQueries()};


            }


             return sqlConfigObject;


        }


    }


And it can be used like shown below:


public class AgentRepository : DbRepositoryBase, IAgentRepository


    {


        #region Fields


         private IQueries _queries;


         private IDbInfrastructure _dbInfrastructure;


         #endregion


        public AgentRepository(DatabaseType type)


        {


            var configuration = type.GetConfiguration();


             _queries = configuration.QueryType;


             _dbInfrastructure = configuration.DbInfrastructure;


          }


   }


It’s quite interesting to use an enum to return an instance of an object of a reference type.


Also, if you have a look at on the usage of the extension method you will see that this approach quite secure because the DatabaseType parameter can not be NULL. 


 


 

 

Evolution of Visual Studio

On April 22, 2010, in Uncategorized, by mako

A while ago I wrote a post about limitations in VS 2010.


After that, I sent my questions  to Cameron Skinner and got very interesting replies that I hope will be interesting for many of you.


First of all, many thanks to Cameron for his replies! 


Maxim: Why / when is Visual Studio going to support runtime type discovery, as static analysis can only go so far?


Cameron: You are absolutely right, we simply don’t have support for dynamic loading of types yet. It is actually worse than just a lack of support for DI / IOC, as any type dynamically loaded ( via LoadAssembly()  for instance ) we don’t discover as that occurs at runtime.


I can tell you this is top of the list for the next release.


Maxim: Why do you not use dynamic dependencies in the actual product itself?


Cameron: We’re making heavy use of MEF in the product, we has greatly enabled us to ship new features outside of the normal shipping vehicles, and has also greatly improved our overall architecture.


 Actually, very nice to get such clear answers from guys from VS team. The answers mean that the next release of Visual Studio will be very interesting and the VS team is doing everything to reach that. 


Did you hear about MEF


MEF it’s a very interesting project created by Microsoft and I tend to write a series of posts about MEF in the near future.

 

VS 2010 shortcut posters.

On April 20, 2010, in Uncategorized, by mako

I think that many developers use shortcuts when working in Visual Studio environment. 


For such developers, the following link might be very interesting.



Enjoy!

 

Using IronRuby in your rules engine

On April 15, 2010, in Uncategorized, by mako

First of all, what IronRuby is? 


So, wikipedia gives us the following description of IronRuby:


IronRuby is an implementation of the Ruby programming language targeting Microsoft .NET framework.


It is implemented on top of the Dynamic Language Runtime, a library running on top of CLR 2.0 that provides dynamic typing and dynamic method dispatch, among other things, for dynamic languages.


Using DLR  allows interoperability with statically typed CLI languages like C#. When it would be useful for you? For example, when we need to implement custome rules engine. 


For instance, 

 

On April 12 I participated in Visual Studio 2010 launch at Moscow. The event was quite interesting. Microsoft evangelists talked about new features in Visual Studio 2010 (Especially, about TFS.). 


More useful session for me was Architectural design and code analysis. Microsoft presented new tool for architects. The tool very interesting (The sample architectural project for VS 2010 you can find at codeplex here.)


But, there are some limitations for the tool and in this post I want to talk about it.


The tool allows us to create dependencies between any classes (services, objects etc) in VS designer mode. Of course, after that code on C#, VB .net (By your choice) will be created. 


That could be great but the dependencies between services are made using static model (Composition is used.). 


I can explain what I mean. 


For example, we have two Data Access Objects:


1. SqlDao (To work with Microsoft SQL Server database);



2. OracleDao (To work with Oracle database).



Also, there is some Aggregator service that processing some customer’s data and writes them to the database.


If we create dependencies between Aggregator service, SqlDao and OracleDao  using VS 2010 architecture tool then c# code would look like this 



I remind you that our application works with Oracle and SqlServer databases and manages what type of database will be used from app.config file. But, using the approach specified above we can’t manage what type of DAO object will be used by depend on what type of 


database we can use now. Two instances of DAO objects will be created anyway. It also mean that Aggregator service must have dublicated methods (functionality) to work with SqlDao and OracleDao functionality.


On the right way all services should be implemented like these



By another words, Aggregator service should have no idea what type of DAO object is used. The managing, what type of DAO object will be used, would be made using such design pattern as Factory of Factories applying app.config settings. 


The architecture tool in Visual Studio doesn’t work using dynamic model (Dependency Inversion Principle, SOLID pricniples) and it is a huge pain for developers who want to create flexible application architecture relying on VS generated code only


In my projects to manage dependencies between objects (services) I use IoC container like Windsor Container


An interesting question is that why Microsoft doesn’t develop IoC?


Also, why guys from VS team didn’t use dynamic model to create dependencies between objects?