1

this is what I got so far, but have to keep passing the DataClassesDataContext around. I wonder if there is a better more centralized way of using the DataClassesDataContext and fill the connectionstring each time the data context is used... Thanks for all the help in advance

public interface ICustomerDataAccess
{
    string GetCustomerName(int customerId);
}

public class CustomerDataAccess : ICustomerDataAccess
{
    private readonly DataClassesDataContext _context;
    public CustomerDataAccess(DataClassesDataContext ctx)
    {
        _context = ctx;
    }

    public string GetCustomerName(int id)
    {
        return _context.Customers.Where(i => i.id == id).FirstOrDefault().name;
    }
}
public class DataAccessFactory
{
    public static ICustomerDataAccess GetCustomerDataAccessObj(DataClassesDataContext ctx)
    {
        return new CustomerDataAccess(ctx);
    }
}
public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService(DataClassesDataContext ctx)
    {
        _customerBL = new CustomerBusinessLogic(new CustomerDataAccess(ctx));
    }

    public string GetCustomerName(int id, DataClasses1DataContext ctx)
    {
        return _customerBL.GetCustomerName(id,ctx);
    }
}
public class CustomerBusinessLogic
{
    ICustomerDataAccess _custDataAccess;
    public CustomerBusinessLogic(ICustomerDataAccess custDataAccess)
    {
        _custDataAccess = custDataAccess;
    }

    public CustomerBusinessLogic(DataClassesDataContext ctx)
    {
        _custDataAccess = new CustomerDataAccess(ctx);
    }
    public string GetCustomerName(int id, DataClassesDataContext ctx)
    {
        _custDataAccess = DataAccessFactory.GetCustomerDataAccessObj(ctx);
        return _custDataAccess.GetCustomerName(id);
    }
}

// and using a code like this on the interface

private void button5_Click(object sender, EventArgs e)
    {
        
        using (var ctx = new DataClassesDataContext)
        {
            CustomerService customerSrv = new CustomerService(ctx);
            textBox1.Text = customerSrv.GetCustomerName(1, ctx);
        }       
    }
Exinell
  • 11
  • 2
  • 1
    You seem to be abusing your `button5_Click` method as [Composition Root](https://mng.bz/K1qZ). Instead of composing your object graph in that method, and possibly duplicating it through many methods in your presentation layer, try moving this out of the presentation classes, into a centralized place, by injecting dependencies into your presentation classes. In your example, it means injecting `CustomerService` into the constructor of the class that holds `button5_Click`. – Steven Feb 02 '21 at 09:07
  • Thanks Steven, that's what I suspected. So I included the property: private CustomerService _custService; and request it in the Form constructor public Form1(CustomerService _custService) { this._custService = _custService; InitializeComponent(); } in the main function of winforms added something like this: Main() { DataContext db = new DataContext(); db.Connection.ConnectionString = "Data Source=*****"; Application.Run(new Form1(new CustomerService(db))); } Would that be sufficient? – Exinell Feb 02 '21 at 15:21
  • Now the GUI events looks a lot cleaner but not sure if the pattern is well implemented. private void button5_Click(object sender, EventArgs e) { textBox1.Text = this._custService.GetCustomerName(1); } – Exinell Feb 02 '21 at 15:25

1 Answers1

0

You can use Generic Repository with Dependency Injection. This is a bit complex structure for the first time but this can solve your problem for your problem.

Also I share with you a nice and detail example. That was created by me

https://github.com/EyupCanARSLAN/N-Tier-Architecture-with-Generic-Repository--Dependency-Injection-And-Ninject/security/dependabot

Also, an article about this topic

https://dotnettutorials.net/lesson/generic-repository-pattern-csharp-mvc/

Eyup Can ARSLAN
  • 692
  • 9
  • 25