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

Using DI for FluentFTP in ASP.NET Core, NET #1199

Closed
kostazol opened this issue Feb 17, 2023 · 14 comments
Closed

Using DI for FluentFTP in ASP.NET Core, NET #1199

kostazol opened this issue Feb 17, 2023 · 14 comments

Comments

@kostazol
Copy link

kostazol commented Feb 17, 2023

**FluentFTP Version: 45.0.3

Framework: .NET 7

Hello. Do you have some best practices for using Fluent FTP with DI? May be FluentFTP need client factory as http client https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory ?

@robinrodricks
Copy link
Owner

@kostazol
Copy link
Author

May you send some micro example?
If I use IAsyncFtpClient via DI into constructor, how I will set ip address, login and password?

@robinrodricks
Copy link
Owner

robinrodricks commented Feb 17, 2023

AsyncFtpClient implements IAsyncFtpClient, cant you use that?

Manually set the properties of AsyncFtpClient once your DI container passes a concrete instance...

Like

MyOtherClass(IAsyncFtpClient client){
    client.Host = ..
    client.Credentials = ...
    client.Connect();
}

And then register the type:

myDIFramework.Register<IAsyncFtpClient,AsyncFtpClient>();

@kostazol
Copy link
Author

kostazol commented Feb 17, 2023

Thank you! But If in the future you will add factory it will be cool.

@robinrodricks
Copy link
Owner

Can you give an example of what you are looking for?

@kostazol
Copy link
Author

kostazol commented Feb 17, 2023

https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory

If we see usually variant it will be the same as using interface and init client in the constructor. But we have named client or typed client and can set client on start application and use it in other places. It will very help if for initialization we have more parameters than ip, login, password.
When start it:

services.AddHttpClient("testClient", client =>
                {
                    client.BaseAddress = new Uri(url);
                })
                .AddHttpMessageHandler<AuthSystemUserTokenToHeaderHandler>(); 

When need client:
var client = _clientFactory.CreateClient("testClient");

@robinrodricks
Copy link
Owner

robinrodricks commented Feb 17, 2023

See even in this example, you are manually setting properties on client, so you can do the same with FluentFTP client. Nothing is stopping you.

Or are you asking for a Factory object and IFactory interface??

And Factory would have methods to create FtpClient and AsyncFtpClient??

@kostazol
Copy link
Author

Or are you asking for a Factory object and IFactory interface??

And Factory would have methods to create FtpClient and AsyncFtpClient??

Yes, I about a factory with methods to create FtpClient and AsyncFtpClient. And also I want to set clients parameters at start (as my example) and create tunned clients from any place.

@parthvnp
Copy link

I can work on adding client factories if needed! @kostazol I think the reason HttpClientFactory exists is because the usage of HttpClient is quite not intuitive as the IDisposable behaviour doesn't conform to with the rest of the framework.

@robinrodricks
Copy link
Owner

@parthvnp Go ahead please!

@parthvnp
Copy link

@robinrodricks @kostazol Here is the spec for design of IAsynFtpClientFactory. Would appreciate feedback and suggestions before I start implementing it. The design inspiration for this Quartz.NET and Microsoft.Extensions.Http.

FTP Client Factory

  • The goal of IAsynFTPClientFactory is to create named (and later typed) FTP clients that can be configured at application start and reused throughout the application. Multiple clients with different configuration can be added and later injected as dependencies. In essence the goal is here: Configure once, use everywhere.
  • FTP Clients are configured by settings up appropriate values for Action<IAsynFTPClientConfigurator>. This interfaces exposes values for settings up FTP Client either by providing FTPConfig instance or by providing the most important properties required to configure the FTP Client. Additionally, the client can also be configured using sections from appsettings.json file if desired.
  • An IAsyncFTPClientBuilder is used to build IAsynFTPClient using the options provided in IAsynFTPClientConfigurator. This class is used internally to build an FTP Client every time Create is called on the factory.
  • Each new call to Create creates a new FTP Client. The onus of disposing the FTP client is on the user of the factory. I am still not sure on this behaviour. For example, it is possible for the factory to manage the lifetime, but this requires the client to know about this implicit behaviour.
  • Possible exceptions can arise if the client wants to
  1. Create a named FTP Client has not been registered.
  2. FTP client with the same name is already registered.
  3. Configuration fails because FTPConfig validation fails. This error won't be surfaced till a call to Create is made.

Minimal examples of the FTP Client Factory API

// create a named FTP Client
IAsyncFTPClientFactory ftpFactory = new DefaultAsyncFTPClientFactory("ftp_client_v1", options => {
   // setup FtpConfig options here
});


// in controller for example

public Example: ControllerBase {
    private IAsyncFTPClientFactory _factory;
    public Example(IAsynFTPClientFactory factory){
        _factory = factory;
    }

    // using the factory to create FTP Client to upload files
    public UploadFile(){
        var client = _factory.Create("ftp_client_v1"); // throws not registered expection if the named client has not been registered
        client.uploadFile(@"D:\Github\FluentFTP\README.md", "/public_html/temp/README.md);
    }
}

@kostazol
Copy link
Author

Everything, is great. But about "The onus of disposing the FTP client is on the user of the factory. I am still not sure on this behaviour." as I know in Microsoft.Extensions.Http usually factory control disposing. I don't know details but it helps control "connection pool" ( HTTP persistent connection ), some discution:
https://stackoverflow.com/questions/54597303/should-i-cache-and-reuse-httpclient-created-from-httpclientfactory

@robinrodricks
Copy link
Owner

@parthvnp Sounds good, you have my blessing to go ahead!

@FanDjango
Copy link
Collaborator

FanDjango commented Mar 21, 2023

I have moved this to the Wiki: https://github.com/robinrodricks/FluentFTP/wiki/Future-Plans

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

4 participants