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

Add an interface for "self describing entities". #18

Open
jmalloc opened this issue Nov 28, 2019 · 1 comment
Open

Add an interface for "self describing entities". #18

jmalloc opened this issue Nov 28, 2019 · 1 comment
Milestone

Comments

@jmalloc
Copy link
Member

jmalloc commented Nov 28, 2019

This would allow applications and handlers to control how they are referenced in error messages.

This would be useful, for example, with projection kit where the actual handler type would be something unfamiliar to the user (such as *sql.adaptor).

@jmalloc jmalloc added this to the 1.0.0-rc.0 milestone Oct 31, 2020
@jmalloc
Copy link
Member Author

jmalloc commented Dec 20, 2020

Beyond just error messages this information should probably considered necessary for features such as #105.

Using projectionkit-based projections as an example once again, a user is implements an SQL-based projection by providing an implementation of sqlprojection.MessageHandler, not dogma.ProjectionMessageHandler. The sqlprojection.New() function is then called to obtain a dogma.ProjectionMessageHandler from the sqlprojection.MessageHandler.

The return type of New() is a *sqlprojection.adaptor. This is the type we see returned by configkit.Entity.TypeName(), and is therefore what is rendered on graphs, etc.

This type name pretty much meaningless to the user. It's useful to know that it's an SQL-based projection, but when rendering markdown/graphs/etc we probably want to see the location of the real implementation. That is, the code the user actually wrote.

I'm still not sure how best to implement this. We could perhaps model it as "wrapped implementations", reminiscent of Go's error wrapping. We could add interfaces like so ...

type ApplicationWrapper struct {
    UnwrapApplication() (interface{}, bool)
}

type HandlerWrapper struct {
    UnwrapHandler() (interface{}, bool)
}

... then, *sqlprojection.adaptor would implement HandlerWrapper and return the underlying sqlprojection.MessageHandler implementation. Note that there's no more specific type we can use than interface{} because we have no idea what the underlying implementation looks like.

This approach would allow for multiple levels of "wrapping" if the value returned by UnwrapHandler() also implemented HandlerWrapper. We could use this to display all of the types involved in a given implementation, or simply to descend until we find the last level and display its type information.

We'd need to change configkit.Entity.TypeName() to instead return a slice of types, or otherwise decide whether TypeName() should show the outer-most or inner-most type and then add an additional TypeNames() method. (As an aside, perhaps since this would be a BC break we could take the opportunity to use naming like GoTypes() to match interopspec/configspec naming, which is less ambiguous).

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

No branches or pull requests

1 participant