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

InitializeAsync MUST not require interface impl #32

Open
dzmitry-lahoda opened this issue Aug 14, 2020 · 3 comments
Open

InitializeAsync MUST not require interface impl #32

dzmitry-lahoda opened this issue Aug 14, 2020 · 3 comments
Labels
feature-request We're considering this issue, but have not decided what to do about it yet

Comments

@dzmitry-lahoda
Copy link

Just do structural stuff.

@YairHalberstadt
Copy link
Owner

I think I would like to do this at some point, but it's not highest priority for me.

Hopefully I'll make a product roadmap soon so people can see what I plan to work on and in which order.

@YairHalberstadt YairHalberstadt added enhancement New feature or request good first issue Good for newcomers labels Aug 14, 2020
@YairHalberstadt
Copy link
Owner

What I think I will do is as follows:

In the [RegisterAttribute] I will add an optional parameter initializeMethod. This must match the name of a public method on the registered type. The method must return void, Task, or ValueTask.

This means you can do this:

public class A
{
    public void SetUp(){}
}

[Register(typeof(A), initializeMethod: nameof(A.SetUp))]
public class Container : IContainer<A>{}

I will keep the IRequiresInitialization interfaces, for cases where you want to make sure you don't forget to register it with an initialize method.

@YairHalberstadt
Copy link
Owner

The following is a possible solution which can be used without adding any new features:

Define your own interface e..g INeedsInitialization, and a module that calls it using a decorator:

public interface INeedsInitialization
{
    /// Must be safe to call multiple times
    public ValueTask InitializeAsync();
}

public class InitializationModule
{
    [DecoratorFactory] public static async ValueTask<T> InitializeAsync(T t) where T : INeedsInitialization
    {
        await t.InitializeAsync();
        return t;
    }
}

Then if you import that module, you can automatically initialize anything that implements that interface.

If there's any type which you don't control and need to initialize you can make a custom decorator specifically for it:

public class SomeClass
{
    public ValueTask PrepareAsync();
}

[Register(typeof(SomeClass))]
public class SomeClassModule
{
    [DecoratorFactory] public static async ValueTask<SomeClass> InitializeAsync(SomeClass someClass)
    {
        await someClass.PrepareAsync();
        return someClass;
    }
}

This also allows you to do much more complex initialization of a type if necessary, but adds a bit of boilerplate.

Would you consider this sufficient?

@YairHalberstadt YairHalberstadt added feature-request We're considering this issue, but have not decided what to do about it yet and removed enhancement New feature or request good first issue Good for newcomers labels Oct 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request We're considering this issue, but have not decided what to do about it yet
Projects
None yet
Development

No branches or pull requests

2 participants