locked
Legacy wep api refactoring RRS feed

  • Question

  • User-1104215994 posted

    Hi,

    I built an asp.net Web API and I am afraid it is legacy :) It was my first try. Now I read some articles (https://www.codeproject.com/Articles/1066348/Web-API-A-Solid-Approach) about web API design etc. and I would like to refactor it. In one of my controller action method, by the way, they are fat, I am querying database table if there are results then I am updating those values. Finally making a projection on the updated table and save it into another table.

    With all of these querying and saving, I couldn't fit the solution on my mind. How can I the repository? I mean It is simple writing get, save, update, etc but all those should be in a transaction, right? I couldn't compose the structure.

    Here is my fat controller action portion which I want to transform.

     #region Check Code Bank database
                //Check Games in our database - all or nothing
                var gameBankResult = await (context.GameBanks.Where(g => g.productCode == initiate.productCode)
                    .Where(l => l.referenceId == null)
                    ).ToListAsync();
                //If we have exact number of games in our database, mark them!
                if (gameBankResult.Count() != 0 && gameBankResult.Count() >= initiate.quantity)
                {
                    for (var index = 0; index < initiate.quantity; index++)
                    {
                        var item = gameBankResult[index];
                        item.referenceId = initiate.referenceId;
                        context.Entry(item).State = System.Data.Entity.EntityState.Modified;
                    }
    
    
                    //Update marked games
                    await context.SaveChangesAsync();
                    
                    //Return marked games in our database
                    var gameBankResultVM = await (context.GameBanks.Where(g => g.productCode == initiate.productCode)
                        .Where(l => l.referenceId == initiate.referenceId)
                        .Take(initiate.quantity)
                        .Select(g => new GameBankInitiationResponseVM()
                        {
                            referenceId = g.referenceId,
                            productCode = g.productCode,
                            quantity = initiate.quantity,
                            initiationResultCode = g.initiationResultCode,
                            validatedToken = g.validatedToken,
                            currency = g.currency,
                            estimateUnitPrice = g.estimateUnitPrice,
                            version = g.version,
                            signature = g.signature,
                            ApplicationCode = g.ApplicationCode,
                            companyToken = null,
                        })).ToListAsync();
    
                    
                    var resultObj = gameBankResultVM[0];
                    
                    var initiateResponse = JsonConvert.SerializeObject(resultObj);
                    var responseDB = JsonConvert.DeserializeObject<InitiateResponse>(initiateResponse);
                    //Adding Response into database
                    context.InitiateResponses.Add(responseDB);
                    await context.SaveChangesAsync();
                    return Ok(resultObj);
    
                }
    
    
                #endregion

    Monday, June 24, 2019 7:30 PM

All replies

  • User1724605321 posted

    Hi  cenk ,

    So that you want to modify your project to create an abstraction layer between the data access layer and the business logic layer of an application. You can refer to below articles for code sample and explanations :

    https://medium.com/@mlbors/using-the-repository-pattern-with-the-entity-framework-fa4679f2139

    https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design

    Your repositories should not have a Save() method is because sometimes as part of a transaction you may work with multiple repositories. And then you want to persist the changes across multiple repositories in one transaction.

    Best Regards.

    Nan Yu 

    Tuesday, June 25, 2019 2:08 AM
  • User1120430333 posted

    https://programmingwithmosh.com/net/common-mistakes-with-the-repository-pattern/

    <copied>

    repositories should not have a Save() or Update() method. I repeat: think of a repository as a collection of domain objects in memory. Do collections have a Save() or Update() method? No!

    <end>

    You UoW should initiate the transaction do the save and commit the transaction.

    Tuesday, June 25, 2019 2:25 AM
  • User-1104215994 posted

    If I can't use update how can I implement my logic? Here is a sample:

    var count = genericRepository.Get(initiate);
    if (count > 0)
    genericRepository.Update(initiate);
    var result = genericRepository.Get(initiate); genericRepository.Add(result); unitOfWork.Complete();

    Tuesday, June 25, 2019 6:15 AM
  • User1120430333 posted

    Maybe, the link will show you how to use UoW and Repository patterns in using an ORM like EF.

    https://medium.com/@mlbors/using-the-repository-pattern-with-the-entity-framework-fa4679f2139

    Tuesday, June 25, 2019 10:16 AM
  • User475983607 posted

    Entity framework is a repository pattern.  Adding another repository on top of EF means you plan to use a different ORM in the future?  Can you explain why you settled on a repository pattern?   Keep in mind, this approach will not clean up or refactor the code base, it will add another layer that replaces EF but you'll have the same amount of code.  A better design pattern. IMHO, for refactoring is the facade pattern.  Basically, move the logic from the actions into another class.  This have been suggested several time on your similar threads.

    Tuesday, June 25, 2019 11:11 AM