0

I am working on a process that requires two different portions of it to make use of an ORM (I am using Insight.Database for this), and I am not sure where this portion of the code belongs, as I am not currently creating an abstraction layer over it but using Insight.Database directly.

An example of the code layout is as follows:

// in Program.cs
// assume we have our connection already created
var vendorInfo = connection.QuerySql("select * from dbo.Vendors where Name = @Vendor", new { Vendor = vendorParam });

// we use reflection to create the correct class, so we can store the class name in the database
var clientFactory = new ClientFactory();
var clientInstance = clientFactory.CreateClient(vendorInfo.ClassName); // this will give us the parent class, all of which implement the method we need

// have the client call its Process() method to do work
clientInstance.Process(vendorInfo.Query);

// in SimpleClient.cs (i.e. a client implementation)
// Each client implementation inherits from a base class and knows how to process itself, so different requests can do different things.
// Each class has a query defined in the database that tells it how to retrieve the specific data it needs, so recompiling/redeploying code is not needed
override void Process(string query)
{
    // This is the part that I am unsure about, as this class also needs
    // to call Insight.Database to retrieve the data it needs to work with.
    // again, assume we have our connection already
    var data = connection.QuerySql(sql);

    // ... do work with the data here ...
}

Now, the problem as indicated by the above comment is that I have more than one (potentially infinite, as many as there are client implementations) class that needs to use Insight.Database to execute some (usually just one, but it could be more than one) query. If I was using a repository or similar, this would not be a problem and I could just pass in the repository interface, but I'm using Insight.Database without any wrapper.

So my question is, should I put Insight.Database into its own project and then re-implement the method signatures that Insight.Database exposes (which would internally just call to Insight.Database itself), or something else? I do not think I can just create the client implementation and pass in actual data it needs because it is always going to be different (in fact the real code is going to have to return it as a raw DataTable since it can contain virtually anything as defined by the corresponding query, and the idea is to make the consuming code as generic as possible to minimize having to add or modify code).

  • 2
    Why aren't you using a repository? – Robert Harvey Jul 20 '17 at 14:59
  • To echo @RobertHarvey you really need something to encapsulate this in its own class. That's the answer. Or call it something different if you want it to return a DataTable. Maybe just called it a FooDataAccess class. – Greg Burghardt Jul 20 '17 at 16:03
  • (in fact the real code is going to have to return it as a raw DataTable since it can contain virtually anything as defined by the corresponding query. Why? Pass the query as you already do, alongside with a mapper or reader that will transform the Datatable into the required object. Abstract yourself from this implementation detail. Let consumers choose the strategy. – Laiv Jul 20 '17 at 16:26
  • @Laiv there's no actual object in many cases, just raw data output that usually is just dumped to a file; the entire goal of this is to have a "table-driven" generic approach that minimizes having to create a new class for each client type (many of them do the same thing just with a different query to retrieve data). That's also why it uses reflection and reads a class name from the database, so we minimize having to deploy code changes. – Wayne Molina Jul 20 '17 at 17:42
  • @RobertHarvey I think that's likely the solution, to just have a repository or similar that wraps the call to Insight.Database, I was trying to avoid having wrapper classes. – Wayne Molina Jul 20 '17 at 17:43
2

If multiple sources refer to different projects in the same solution, consider create a new project as a "Shared Component", then let other projects add it as a reference. There might be other reusable components that could go this "Shared Component" project as you move further into the development as well. This at least would make your code easier to maintain in the long term.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.