Accessing SQL stored procedures The following code is from the DataAccess layer that calls the SQL stored procedure and returns the result set back to the calling code.

public class CoffeeDataAccess : ICoffeeDataAccess
    {
        private readonly Database coffeeDatabase;

        public CoffeeDataAccess(ICoffeeShopDatabaseFactory factory)
        {
            this.coffeeDatabase = factory.GetCoffeeDatabase();
        }

        public async Task&lt;IEnumerable&lt;Coffee&gt;&gt; GetAllAvailableCoffees()
        {
            IEnumerable&lt;Coffee&gt; coffees = await this.ExecuteCommandAsync("spGetAllCoffees");
            return coffees;
        }

        public async Task&lt;IEnumerable&lt;Coffee&gt;&gt; GetCofeesOfTheWeek()
        {
            IEnumerable&lt;Coffee&gt; coffees = await this.ExecuteCommandAsync("spGetCoffeesOfTheWeek");
            return coffees;
        }


        private async Task&lt;IEnumerable&lt;Coffee&gt;&gt; ExecuteCommandAsync(string spName)
        {
            IList&lt;Coffee&gt; coffees;

            using (DbCommand command = this.coffeeDatabase.GetStoredProcCommand("dbo" + spName))
            {

                Task&lt;IDataReader&gt; dataReaderTask =
                    Task&lt;IDataReader&gt;.Factory.FromAsync(this.coffeeDatabase.BeginExecuteReader, this.coffeeDatabase.EndExecuteReader, command, null);

                using (IDataReader reader = await dataReaderTask)
                {
                    coffees = new List&lt;Coffee&gt;();
                    while (reader.Read())
                    {
                        Coffee c = new Coffee();
                        c.Id = int.Parse(reader["ID"].ToString());
                        c.Name = reader["Name"].ToString();
                        c.ShortDesc = reader["ShortDesc"].ToString();
                        c.LongDesc = reader["LongDesc"].ToString();
                        c.Price = decimal.Parse(reader["Price"].ToString());
                        c.ImageUrl = reader["ImageUrl"].ToString();
                        c.ImageThumbnailUrl = reader["ImageThumbnailUrl"].ToString();
                        c.CategoryId = int.Parse(reader["CategoryId"].ToString());
                        coffees.Add(c);
                    }
                }
            }

            return coffees;
        }

    }


The CoffeeDataAccess object is newly instantiated every time when a client code asks for it from the IoC container (registered as Trasient in ASP.NET Core - startup class). Is the method name ExecuteCommandAsync thread safe or not?

I think it is because each time a new instance of the CoffeeDataAccessclass is created but I'm not sure.
Haven't tested the code, but the code should be thread safe! All ExecCommandAsync methods are called from within asynchronous functions.