Click here to Skip to main content
15,886,809 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using a third party library that has a connection object called a SessionManager. The SessionManager allows you to create different types of requests for querying, adding or modding. I am writing some extension methods to try and make the coding faster as I tend to repeat code for a lot of projects when using this component. Here's the regular code that I would use to query a list of cusotmers:
C#
SessionManager manager = new SessionManager();
manager.OpenConnection(filename);
IMsgSetRequest MsgRequest = SessionManager.CreateMsgSetRequest();
ICustomerQuery query = MsgRequest.AppendCustomerQuery();
query.ActiveStatus.SetValue(ENActiveStatus.All);
IResponse response = SessionManager.DoRequests(MsgRequest);
if(response.StatusCode == 0) { return (ICustomerRetList)response.Detail; }
else { throw new Exception("Unknown error querying customers: " + response.StatusMessage; }

I don't know if it's possible using extensions, but I would like to be able to be able to change my code to do something like this:
C#
SessionManager manager = new SessionManager();
return manager.Customers.QueryAll();
The idea being that I could then code some standard queries like
manager.Customers.QueryActive();
and
manager.Vendors.QueryAll();
The hard part that I am not able to figure out is the part between the SessionManager and the actual extension function for the query. It doesn't seem like you can do a nested class with extensions.

What I have tried:

I've tried creating a static class within a static class, but I get the error that extension methods must be in a top level class. I tried the following code, but the compiler didn't seem to understand what I was trying:
public static ICustomerRetList Customer.QueryAll(this SessionManager manager)
Posted
Updated 8-Feb-17 5:52am

You can't created "nested" extension methods, but your extension method can return an instance of a class / struct with other methods on it.

Try something like this:
C#
public static class MyExtensions
{
    public static CustomerWrapper Customer(this SessionManager session)
    {
        return new CustomerWrapper(session);
    }
}

public struct CustomerWrapper
{
    public CustomerWrapper(SessionManager session)
    {
        Session = session;
    }
    
    public SessionManager Session { get; }
    
    public ICustomerRetList QueryAll()
    {
        ...
    }
}

You'll just need to add parentheses after the Customer call:
C#
SessionManager manager = new SessionManager();
return manager.Customer().QueryAll();
 
Share this answer
 
v2
You can do something like this

public class CustomerManager
{
    private SessionManager sessionManager;

    public CustomerManager(SessionManager sessionManager)
    {
        this.sessionManager = sessionManager;
    }

    public ICustomerRetList QueryActive()
    {
        // use this.sessionManager to query active customers and return them
    }
}

public static class MyExtensions
{
    public static CustomerManager Customers(this SessionManager sessionManager)
    {
        return new CustomerManager(sessionManager);
    }
}


then use it like

SessionManager manager = new SessionManager();

manager.Customers().QueryActive();


You can do the same thing with Vendors, so have a VendorManager class.
 
Share this answer
 
Comments
Richard Deeming 8-Feb-17 13:08pm    
Snap! :D
F-ES Sitecore 9-Feb-17 4:04am    
Fools seldom differ :d
hpjchobbes 8-Feb-17 21:16pm    
So the idea is create an extension for my sub designation which returns a 'manager' of this type, and the 'manager' only has a public constructor that takes my connection object, and has functions for the query. This seems like it would work.

From a 'best practices' of programming, would this be the ideal way to go if you were dealing with this kind of interface? It seems odd to have to jump through a few different classes to get here.
F-ES Sitecore 9-Feb-17 4:03am    
I only really proposed that solution as you were asking about extension methods. In reality I would just create the CustomerManager class manually, I wouldn't bother accessing it via an extension, so rather than

sm.Cusomers().QueryActive();

I would

CustomerManager cm = new CustomerManager(sm);
cm.QueryActive();

It just makes the code a bit more explicit and also lends itself better to unit testing etc if you use interfaces.
You can't create your extension methods using composite names - in fact, you can't create any method using a composite name like that. So, while you could have CustomerQueryAll, you can't have Customer.QueryAll. What it looks like you really want, is to have a specialization of the extension method so you would have something like this:
C#
public static ICustomerRetList QueryAll(this Customer customer)
{
  // Do something here.
}
That way, your code manager.Customer.QueryAll() would work because you are passing the customer in now.
 
Share this answer
 
hi, it seems the third party library you are using is not allowing you to create extension method.
either it will be a generic class or something which is not allowing.
you can check the reason in this link
 
Share this answer
 
Comments
Richard Deeming 8-Feb-17 11:29am    
If you read the link you posted, you'll see that the limitation applies to the class in which the extension method is defined, NOT the class which the method extends.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900