Entity Framework not saving data to database on context.SaveAsync() while using Autofac

Hi,

Recently I was using Entity Framework with a DB first approach in an application and using the Repository pattern with Unit of Work to have easy management of DB operations.

So my repository constructor accepted an IDataContext object (IDataContext is a custom interface I had written which encapsulates the DbContext generated after adding Entity Data model. Refer sample code below.

RepositoryBase:

public class RepositoryBase<TEntity> : IRepositoryBase<TEntity>
where TEntity : class

{

        public RepositoryBase(IDataContext context)

        {

        }

}

The UnitOfWork class had a constructor that accepted the ILifetimeScope object and using this object, I was resolving the context in the constructor. I also had a couple of repositories specified as properties in this class. Refer sample code below.

UnitOfWork.cs

public class UnitOfWork : IUnitOfWork

{

    public UnitOfWork(ILifetimeScope scope)

    {
        this.scope = scope.
        this.Context = this.scope.Resolve<IDataContext>();

    }

    public Task<int> SaveAsync()

    {

        return this.Context.SaveAsync();

    }

   // Repositories

    public IRepositoryBase<SampleClass> SampleRepository

    {

        get
        {
            if(this.sampleClassRepository == null) this.sampleClassRepository = this.scope.Resolve<IRespositoryBase<SampleClass>>();    // Observe above line later
             return this.sampleClassRepository;
        }

    }

}

The code that was using this repository was something like

using(var uow = this.scope.Resolve<IUnitOfWork>())
{

    uow.SampleRepository.Insert(newEntity);
    uow.SaveAsync();    // This should actually save above new entity into DB but it wasn't saving anything.
}

The problem with this approach was that When I was working with the repository, Autofac initially sees that the repository object has not been created and so creates a new object by resolution by injecting a NEW CONTEXT object as it sees that repository constructor requires an IDataContext object.

So because of this issue, we end up with 2 different contexts, one which just got created while trying to access the repository and this also has the change (insert), and the other which got created while creation of UnitOfWork object. And what happens is insert action goes into repository context object and Save action works upon the UnitOfWork’s context object. Hence, nothing fails but nothing happens in DB as well.

To make sure that repositories are also using the same context as UnitOfWork, what we can do is to pass the unitOfWork’s context to the Resolve method of ILifetimeScope as shown below.

if(this.sampleClassRepository == null) 
    this.sampleClassRepository = 
    this.scope.Resolve<IRespositoryBase<SampleClass>>
        (new TypedParameter(typeof(IDataContext), this.Context));

This is present in the UnitOfWork class. And this.Context refers to unitOfWork’s context. This statement ensures that when repository instance is being created, instead of creating a new context, we’re going to reuse the context of unitOfWork and so any Save operations performed would thus perform the operations on the database as well.

Hope this helps!

Reference : http://docs.autofac.org/en/latest/resolve/parameters.html

Posted in .NET, General | Tagged , , , , , , , | Leave a comment

Resolving Azure Data Lake Authorization Issue

Hi,

While trying to access Azure Data Lake Store from my application, I encountered the below exception.

The client 'guid' with object id 'guid' does not have authorization 
to perform action 'Microsoft.Authorization/permissions/read' 
over scope '/subscriptions/guid....

Resolution :

I realized that I had not given permission to the Active directory application in the Data Explorer tab in ADLS. To give permission, open Data Explorer –> Access –> Add –> Search for your AD application, Give Read, Write, Execute permission –> Save.

This should resolve the issue.

Hope this helps!

Posted in .NET, General | Tagged , , , , , | Leave a comment

Resolving IContainer in Constructor when using Autofac

Hi,

While using Unity as an Inversion of Control and Dependency Injection container, there is an option to directly inject the container into a class’s constructor by placing the IUnityContainer interface as a constructor parameter. This container can then be used by the class members for further resolution.

This option is not directly available in Autofac. If we put a parameter of IContainer type in a class’s constructor, then we get the below exception.

None of the constructors found with 
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 
on type 'your_class' can be invoked with the 
available services and parameters:

Cannot resolve parameter 'Autofac.IContainer container' 
of constructor 'Void .ctor(Autofac.IContainer)'.

Instead, you can inject the IComponentContext or the ILifetimeScope interfaces in the constructor of your class and use the injected instance of either of these for resolving further dependencies.

Example:

public class SampleClass
{
    public SampleClass(ILifetimeScope lifetimeScope)
    {
        // basically using the lifetimescope parameter 
        // as a container for resolving other dependencies.

        var someOtherDependency = 
             lifetimeScope.Resolve<ISomeOtherInterface>();

    }
}

Hope this helps!

 

Posted in General | Tagged , , , , | Leave a comment

Resolving “Value does not fall within the expected range” ArgumentException while reporting custom health events in Azure service fabric

Hi,

If you’re working with Azure Service Fabric, there are chances you might be using the cluster Health Management APIs provided by SF SDK. And if you’re using those, then you would obviously be posting some custom health events at either your service level, application level or instance level with a source Id, health property and a human-readable description.

Solution :  The one thing to note here is that the Description field of HealthInformation class has a limit of 4095 characters. This is nowhere mentioned in the documentation but it’s there. And if the description is more than that, while reporting you would get the below exception.

Exception Type : System.Argument Exception
Message : Value does not fall within the expected range.
Inner Exception :  null
Stack Trace : 
   at System.Fabric.Interop.NativeClient.IFabricHealthClient3.ReportHealth(IntPtr healthReport)
   at System.Fabric.FabricClient.HealthClient.ReportHealthHelper(HealthReport healthReport)
   at System.Fabric.Interop.Utility.<>c__DisplayClass13.<WrapNativeSyncInvoke>b__12()
   at System.Fabric.Interop.Utility.WrapNativeSyncInvoke[TResult](Func`1 func, String functionTag, String functionArgs)
   at System.Fabric.Interop.Utility.RunInMTA(Action action)
   at System.Fabric.FabricClient.HealthClient.ReportHealth(HealthReport healthReport)
   at ….. your file.

So, in case you run into this exception at the point of reporting, make sure you double-check the description length and in-general all the data that you’ve added to the health report object.

Hope this helps!

Posted in .NET, General | Tagged , , , , , , , , | Leave a comment

Check if service bus topic/subscription/queue exists with SAS key not having Manage permission

Hi,

Consider a scenario where you’ve developed an application health monitoring type system which validates your application at application startup/periodically. Now as part of that if your application uses Azure service bus queues, topics, subscriptions, then it would be good to verify that they all exist before your application actually starts its work.

So your initial thought would be to use NamespaceManager class from the Microsoft.ServiceBus assembly. This class provides <entity>Exists() methods for all the above. However, one point to note here is that NamespaceManager class requires Manage permission to be present to the SAS key from the connection string.

As a security measure, the general advise is to NOT use a SAS key with manage permission and to use one with Send/Listen permissions.

1

So for checking if the entities exist, we can use the TopicClient, SubscriptionClient, QueueClient classes from Microsoft.ServiceBus.Messaging assembly. Check below code. Click for full size image.

2_updated

 

In the above snippet, each of the .Peek() (Or PeekAsync()) methods will throw an exception (Entity not found) if the corresponding entity doesn’t exist and passes if they exist. This check can be used to determine if the entities exist or not.

P.S: There are other ways too but this is relevant if you do not want to send/receive from these service bus entities.

Hope this helps!

Posted in .NET, C#, General | Tagged , , , , , , , , , , , | Leave a comment

Out parameters in Async methods.

A little while ago, I wanted to have an asynchronous method that returned a string but also populated an integer “out” parameter. So I started writing the method as below

// Note: This will give compiler error.
private async Task<string> GetUserDetails(out int userRegionCode)
{
    userRegionCode=105;
    return "samplestring";
}

However, the compiler showed an error stating that out parameters were not allowed for an asynchronous method. After searching for it online and reading through this thread (gives a detailed explanation), I found that it’s a limitation of the CLR.

So instead I used a Tuple to return both the values that I wanted to use. You can read more about Tuple and its usages here.

Sample code below.

... 
... 
// calling code. 
var userDetails = await GetUserDetails(userId); 
Console.WriteLine("Username : {0}", userDetails.Item1); 
Console.WriteLine("User Region Id : {0}", userDetails.Item2); 
... 
... 

private async Tuple<string,int> GetUserDetails(int userId) 
{ 
    return new Tuple<string,int>("Amogh",105); 
    // Note that I can also use the existing helper method (Tuple.Create) here. Read more about it here. 
}

Hope this helps!

Posted in .NET | Tagged , , , | Leave a comment

Cannot access a disposed object. ‘System.Net.Http.StringContent’ While having retry logic.

Hi,

I faced this scenario today when I was trying to make an HttpPost call using a retry logic wherein I was getting an ObjectDisposedException while trying to retry for the first time.

Exception Message:

Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'

My calling code was something like this.

var httpContent = GetHttpContent();

retryPolicy.ExecuteWithRetry(async () => await httpClient.PostAsync(url, httpContent));

The problem with this code is, when the first call to PostAsync is made and it fails, the httpContent object is disposed. This is as designed in the HttpClient class. Refer the comment in this method. Although this seems odd, they intent to do this so that the user doesn’t have to do this explicitly and also to avoid the same request being Posted more than once.

So what happens is, when the first call fails, httpContent is disposed, then as we have retry mechanism, it tries to make the post call again, now with a disposed object and hence this time, the call fails with an ObjectDisposedException.

An easy way to resolve this is to NOT use a variable to store httpContent and instead, create http content directly while making the call. Something like this.

retryPolicy.ExecuteWithRetry(async () => await httpClient.PostAsync(url, GetHttpContent()));

This will make sure that every subsequent retry has a new httpContent object created.

Hope this helps!

References:

  1. http://stackoverflow.com/questions/19260060/retrying-httpclient-unsuccessful-requests
  2. http://stackoverflow.com/questions/29369945/objectdisposedexception-on-httpclient
  3. http://stackoverflow.com/a/15708633/2377928
  4. http://stackoverflow.com/a/25495500/2377928
  5. https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpClient.cs
  6. https://github.com/dotnet/corefx/issues/1794
Posted in General | Tagged , , , , , , , , , , , , | Leave a comment