Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write object initialization code for c# object, not expression (for more general application to c# projects) #76

Open
jeanluc33 opened this issue Mar 16, 2018 · 2 comments

Comments

@jeanluc33
Copy link

I notice in the ExportGenerator.cs class there is a method, GenerateText(Expression expression, ExpressionSourceType source) that can generate object initialization code from an expression.

Is there a straightforward way to do this from a c# object, like this: GenerateText(Object object, ExpressionSourceType source)

In this way, assuming dependencies could be limited, ObjectExporter could be highly useful as a nuget package for inclusion in many projects where code generation from an object (state) is required.

@OmarElabd
Copy link
Owner

Currently ObjectExporter does not use reflection to generate the C# serialized text, so at the moment there wouldn't be anything where you could serialize an object directly to C#. I have thought about creating something like this in the past, but i did not think it would be useful for anyone. Did you have any particular use cases in mind for such a package?

@jeanluc33
Copy link
Author

jeanluc33 commented Mar 20, 2018

Here's my use case.

Use Case for Serialization Objects to C# initialization code -- For Applications involving Dummy Middleware Implementations (Generate initialization code to allow code isolation on legacy code, integration/unit tests)

Essentially, what this gives us compared to existing approaches is a level of automation. Suppose we have Middleware that retrieves data from external applications and exposes the data in terms of Domain objects (POCOs) for use by your application(s).

public class MiddleWare : ICustomerMiddleWare {

public Customer GetCustomer {
....
return customer;
}

public class Customer {

public EmailPreferences GetEmailMarketingPreferences(){
... reach out to DB to get current EmailPreferences...
}

public Address GetCurrentMailingAddress{
...
get {

.. reach out to DB to get Mailing address
}
}

public Boolean HasOpenCases{
...
get {
... reach out to customer relation system to see if customer has open cases
}
}

etc.

If I could get these objects in C# initialization code, I would have a strongly-typed initialization that could be easily modified to support common operations. Right off the bat, I could generate C# initialization code that represents the middleware in a certain state (a Dummy Middleware implementation, or perhaps a Dummy repository implementation depending on the exact scenario). By returning the objects that I create from the initialization code in a class that implements the web service interface (e.g. ICustomerMiddleware), I'd have an alternative implementation that would eliminate the dependencies on the external system(s).

In terms of the example above, we could get a Customer object from the Middleware class above on the GetCustomer method. We could get the c# initialization code for the object, and then create a new StaticMiddleware class that implements the ICustomerMiddleware interface and returns the initialization code for the c# method.

For legacy code where the Customer class has two dozen or more properties of Domain/POCO objects, the generation of the initialization code would essentially automate an otherwise time-consuming process. Is this something mocking frameworks take care of? Yes and no. The problem is, mocking frameworks are not automated; it is a manual process to set up mock objects. For legacy code with nested objects (3-4 levels), it may be impractical or time-consuming to set up mock objects.

On the other hand, if we can generate the c# initialization code, we can use the generated code for our middleware, allowing development on the front-end systems that depend on the middleware to proceed.

So we have these benefits of c# object initialization code versus using something like XML serialization:

  1. Strongly typed initialization code allows compiler to catch some errors
  2. Initialization code can easily be tweaked to represent different scenarios of returned objects (e.g. for generating mock objects for unit tests)
  3. We can use the corresponding c# intialization code for an Object for each method of a middleware to represent the middleware in a certain state. This in turn is essentially an automatically generated alternative implementation of the middleware (assuming the middleware implements an interface).

My goal personally would be to take code from number 3 above and gradually set up proper mock objects for unit tests (number 2) but having number 3 would make that tremendously easier to get started at first.

In conclusion, being able to generate c# object initialization code from nested objects would be useful to many people, especially those in "Working Effectively with Legacy Code" (Feathers) situations where sprawling middleware exists but is either partially or completely not under unit tests. In my experience in application development, such code exists at many organizations (especially those organizations whose main product isn't software).

With the ability to essentially capture objects and generate the c# initialization code, we'd have a powerful tool to deal with external dependencies during development and transition the code away from sprawling methods that lack unit test coverage. In some cases, the c# initialization code would either directly be useful in making inputs/arrangements for unit tests; in other cases it would at least helping to deal with some dependencies and get past "chicken and egg" type problems that block setting up unit tests for legacy code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants