Closed cesarecaoduro closed 5 months ago
Can I have an example of what you want from this library? After all, DI and other services can be added simply by installing the Nuget package if necessary
In a complex application, there are services that you may want to have instantiated as singleton. Services like logs and telemetry are required across the entire application, and you want to make sure you decouple those from their implementation inside the different commands. Example: I would like to instantiate a telemetry client in the application entry point as singleton (using some sort of builder), and then have that available in the constructor of the command.
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
[Journaling(JournalingMode.NoCommandData)]
public class SimpleCommand: IExternalCommand
{
private readonly ITelemetryService _telmetryService;
public SimpleCommand(ITelmetryService telemetryService, ExternalCommandData commandData, ref string message, ElementSet elements)
{
//Code here
_telemetryService = telemetryService;
}
}
Very common pattern in web development with netcore, but so far I haven't seen a lot of these implementation in the Revit world. The only one is the OnBox framework that I pointed out, but I see I am not sure that has been taken care of in the last couple of year. You have done an amazing work in pulling together this toolset for Revit developers, and this would just be ice on the cake 😄
Here's how you can do it:
Microsoft.Extensions.DependencyInjection
public static class Host
{
private static IServiceProvider _serviceProvider;
public static void Start()
{
var services = new ServiceCollection();
services.AddTransient<RevitAddin.Commands.HostedCommand>();
services.AddTransient<RevitAddinView>();
services.AddTransient<IRevitAddinViewModel, RevitAddinViewModel>();
_serviceProvider = services.BuildServiceProvider();
}
public static T GetService<T>() where T : class
{
return _services.GetService<T>();
}
}
Or create a host using Microsoft.Extensions.Hosting
public static class Host
{
private static IHost _host;
public static void Start()
{
var builder = Microsoft.Extensions.Hosting.Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
{
ContentRootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly()!.Location),
DisableDefaults = true
});
builder.Services.AddTransient<RevitAddin.Commands.HostedCommand>();
builder.Services.AddTransient<RevitAddinView>();
builder.Services.AddTransient<IRevitAddinViewModel, RevitAddinViewModel>();
_host = builder.Build();
_host.Start();
}
public static T GetService<T>() where T : class
{
return _host.Services.GetService(typeof(T)) as T;
}
}
Create an intefrace. It is required so that the host can create an instance of the new class with resolved dependencies
public interface IHostedCommand
{
void Execute(ExternalCommand shell);
}
Create a command and implement the IHostedCommand interface. In the class constructor specify all the dependencies you need. You can use the primary constructor available in C#12
public class HostedCommand (RevitAddinView view, ILogger logger, MyDependency dependency) : IHostedCommand
{
public void Execute(ExternalCommand shell)
{
logger.Debug("Hello from DI");
view.ShowDialog();
}
}
In the ExternalCommand that attaches to the Revit ribbon, get a new instance of the previously created HostedCommand and call the Execute method
[UsedImplicitly]
[Transaction(TransactionMode.Manual)]
public class RibbonCommand : ExternalCommand
{
public override void Execute()
{
Host.GetService<RevitAddin.Commands.HostedCommand>().Execute(this);
}
}
@cesarecaoduro I create this package ricaun.DI with the core DI implementation based on the Onbox code.
And here are some extensions for Revit Api: ricaun.Revit.DI
Here is a full example: https://github.com/ricaun-io/RevitAddin.DI.Example
@ricaun why did you decide to make your own container instead of Microsoft's implementation ? What's the benefit ?)
I already used the Onbox framework when Thiago released, and I needed a simple DI package to add in any project without adding any random dependency. Microsoft.Extensions.Hosting have too many dependencies, if you only need DI does not worth. https://www.nuget.org/packages/Microsoft.Extensions.Hosting#dependencies-body-tab
If you need only DI, you can use this package without any problems https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection
@cesarecaoduro preview release with DI implementation and samples: https://github.com/Nice3point/RevitTemplates/releases/tag/4.0.0-preview.1.0
This is amazing... I am on it to do some testing.
On Sun, Mar 10, 2024 at 10:29 PM Roman @.***> wrote:
@cesarecaoduro https://github.com/cesarecaoduro preview release with DI implementation and samples: https://github.com/Nice3point/RevitTemplates/releases/tag/4.0.0-preview.1.0
— Reply to this email directly, view it on GitHub https://github.com/Nice3point/RevitTemplates/issues/39#issuecomment-1987193294, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGJG6AY55VWQCL64UBWBBITYXQ7YXAVCNFSM6AAAAAA2672P2WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBXGE4TGMRZGQ . You are receiving this because you were mentioned.Message ID: @.***>
@cesarecaoduro great, if you have any suggestions let me know, we still have half a month before public release
Maybe a stupid question: how do I install the templates if they are in preview? Are you also looking at the possibility of having a similar solution for Civil3D and other Autocad based products?
On Mon, Mar 11, 2024 at 11:00 AM Roman @.***> wrote:
@cesarecaoduro https://github.com/cesarecaoduro great, if you have any suggestions let me know, we still have half a month before public release
— Reply to this email directly, view it on GitHub https://github.com/Nice3point/RevitTemplates/issues/39#issuecomment-1988026515, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGJG6A4XY27VWFUK2RC22DLYXV6CBAVCNFSM6AAAAAA2672P2WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBYGAZDMNJRGU . You are receiving this because you were mentioned.Message ID: @.***>
@cesarecaoduro Nuget generates a command to install)
dotnet new install Nice3point.Revit.Templates::4.0.0-preview.1.0
There are no plans for Autocad/Civil, I abandoned them a long time ago and moved to Revit. Autodesk are similarly uninterested as well
@cesarecaoduro released. Tooltips with description you will see when creating a project in IDE. Description: https://github.com/Nice3point/RevitTemplates/wiki/Templates Samples: https://github.com/Nice3point/RevitTemplates/tree/main/samples
Great job! Thanks for your commitment to the open source community.
Cesare Caoduro
From: Roman @.> Sent: Thursday, April 4, 2024 12:12:08 AM To: Nice3point/RevitTemplates @.> Cc: Cesare Caoduro @.>; Mention @.> Subject: Re: [Nice3point/RevitTemplates] How to add Dependency Injection support (Issue #39)
@cesarecaodurohttps://github.com/cesarecaoduro released Description: https://github.com/Nice3point/RevitTemplates/wiki/Templates Samples: https://github.com/Nice3point/RevitTemplates/tree/main/samples
— Reply to this email directly, view it on GitHubhttps://github.com/Nice3point/RevitTemplates/issues/39#issuecomment-2034569347, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGJG6AZ6WXVBIQT7KQN6HRTY3P52RAVCNFSM6AAAAAA2672P2WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZUGU3DSMZUG4. You are receiving this because you were mentioned.Message ID: @.***>
It will be extremely useful to add a mechanism for integrating dependency injection in the current template, similar to what has been done by OnBox . Services like telemetry or logs should be instantiated in the application and made available to all the commands.