Skip to content

Commit

Permalink
Add dependency injection sample (nanoframework#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
bytewizer authored Jul 6, 2022
1 parent bc13bf4 commit 21c917f
Show file tree
Hide file tree
Showing 15 changed files with 463 additions and 0 deletions.
35 changes: 35 additions & 0 deletions samples/DependencyInjection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Dependency injection sample pack

A Dependency Injection (DI) Container provides functionality and automates many of the tasks involved in Object Composition, Interception, and Lifetime Management. These API mirrors as close as possible the official .NET
[Dependency Injection](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection). Exceptions are mainly derived from the lack of generics support in .NET nanoFramework.

## Samples

### Dependency injection application container sample

[SlowBlink](./SlowBlink) shows how to create a dependency injection application container including gpio and logging. Project sample will require a working led connected to a GPIO port.

### Dependency injection usage sample

[Simple](./Simple) shows how to create a very simple dependency injection object.

## Building the samples

1. Start Microsoft Visual Studio 2022 (VS 2019 and VS 2017 should be OK too) and select `File > Open > Project/Solution`.
1. Starting in the folder where you unzipped the samples/cloned the repository, go to the subfolder for this specific sample. Double-click the Visual Studio Solution (.sln) file.
1. Press `Ctrl+Shift+B`, or select `Build > Build Solution`.

## Run the sample

The next steps depend on whether you just want to deploy the sample or you want to both deploy and run it.

### Deploying the sample

- Select `Build > Deploy Solution`.

### Deploying and running the sample

- To debug the sample and then run it, press F5 or select `Debug > Start Debugging`.

> **Important**: Before deploying or running the sample, please make sure your device is visible in the Device Explorer.
> **Tip**: To display the Device Explorer, go to Visual Studio menus: `View > Other Windows > Device Explorer`.
64 changes: 64 additions & 0 deletions samples/DependencyInjection/Simple/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using System.Diagnostics;

using nanoFramework.DependencyInjection;

namespace nanoFramework.Simple
{
public class Program
{
public static void Main()
{
// registering services
var serviceProvider = new ServiceCollection()
.AddSingleton(typeof(ServiceObject))
.AddSingleton(typeof(RootObject))
.BuildServiceProvider();

// create a service provider to get access to the RootObject
var service = (RootObject)serviceProvider.GetService(typeof(RootObject));
service.ServiceObject.Three = "3";

// create an updated instance of the root object
var instance = (RootObject)ActivatorUtilities.CreateInstance(
serviceProvider, typeof(RootObject), 1, "2"
);

Debug.WriteLine($"One: {instance.One}");
Debug.WriteLine($"Two: {instance.Two}");
Debug.WriteLine($"Three: {instance.ServiceObject.Three}");
Debug.WriteLine($"Name: {instance.ServiceObject.GetType().Name}");
}

public class ServiceObject
{
public string Three { get; set; }
}

public class RootObject
{
public int One { get; }

public string Two { get; }

public ServiceObject ServiceObject { get; protected set; }

public RootObject(ServiceObject serviceObject)
{
ServiceObject = serviceObject;
}

// constructor with the most parameters will be used for activation
public RootObject(ServiceObject serviceObject, int one, string two)
{
ServiceObject = serviceObject;
One = one;
Two = two;
}
}
}
}
34 changes: 34 additions & 0 deletions samples/DependencyInjection/Simple/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Simple")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Simple")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

41 changes: 41 additions & 0 deletions samples/DependencyInjection/Simple/Simple.nfproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<NanoFrameworkProjectSystemPath>$(MSBuildExtensionsPath)\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
</PropertyGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ProjectGuid>333cb8a6-a3a8-4a3d-8f84-bfb7e4de103f</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<FileAlignment>512</FileAlignment>
<RootNamespace>nanoFramework.Simple</RootNamespace>
<AssemblyName>nanoFramework.Simple</AssemblyName>
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
</PropertyGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib">
<HintPath>packages\nanoFramework.CoreLibrary.1.12.0\lib\mscorlib.dll</HintPath>
</Reference>
<Reference Include="nanoFramework.DependencyInjection">
<HintPath>packages\nanoFramework.DependencyInjection.1.0.0.11\lib\nanoFramework.DependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
<ProjectExtensions>
<ProjectCapabilities>
<ProjectConfigurationsDeclaredAsItems />
</ProjectCapabilities>
</ProjectExtensions>
</Project>
27 changes: 27 additions & 0 deletions samples/DependencyInjection/Simple/Simple.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32519.379
MinimumVisualStudioVersion = 10.0.40219.1
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "Simple", "Simple.nfproj", "{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}.Release|Any CPU.Build.0 = Release|Any CPU
{333CB8D6-A3A8-4A3D-8F84-BFB7E4DE103F}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1EC40AA7-C769-4EBB-9C18-8CE1692239EB}
EndGlobalSection
EndGlobal
5 changes: 5 additions & 0 deletions samples/DependencyInjection/Simple/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="nanoFramework.CoreLibrary" version="1.12.0" targetFramework="netnano1.0" />
<package id="nanoFramework.DependencyInjection" version="1.0.0.11" targetFramework="netnano1.0" />
</packages>
35 changes: 35 additions & 0 deletions samples/DependencyInjection/SlowBlink/Application.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using System;

using Microsoft.Extensions.Logging;

namespace nanoFramework.SlowBlink
{
internal class Application
{
private readonly ILogger _logger;
private readonly IHardwareService _hardware;
private readonly IServiceProvider _provider;

public Application(IServiceProvider provider, IHardwareService hardware, ILoggerFactory loggerFactory)
{
_provider = provider;
_hardware = hardware;
_logger = loggerFactory.CreateLogger(nameof(Application));

_logger.LogInformation("Initializing application...");
}

public void Run()
{
var ledPin = 23;

_logger.LogInformation($"Started blinking led on pin {ledPin}.");
_hardware.StartBlinking(ledPin);
}
}
}
32 changes: 32 additions & 0 deletions samples/DependencyInjection/SlowBlink/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using nanoFramework.Logging.Debug;
using nanoFramework.DependencyInjection;

using Microsoft.Extensions.Logging;

namespace nanoFramework.SlowBlink
{
public class Program
{
public static void Main()
{
ServiceProvider services = ConfigureServices();
var application = (Application)services.GetRequiredService(typeof(Application));

application.Run();
}

private static ServiceProvider ConfigureServices()
{
return new ServiceCollection()
.AddSingleton(typeof(Application))
.AddSingleton(typeof(IHardwareService), typeof(HardwareService))
.AddSingleton(typeof(ILoggerFactory), typeof(DebugLoggerFactory))
.BuildServiceProvider();
}
}
}
22 changes: 22 additions & 0 deletions samples/DependencyInjection/SlowBlink/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("nanoFramework.SlowBlink")]
[assembly: AssemblyCompany("nanoFramework Contributors")]
[assembly: AssemblyProduct(".NET nanoframework nanoFramework.DependencyInjection Sample")]
[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]

//////////////////////////////////////////////////////
// this assembly does NOT have a native counterpart //
//////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
[assembly: AssemblyNativeVersion("0.0.0.0")]
////////////////////////////////////////////////////////////////

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
65 changes: 65 additions & 0 deletions samples/DependencyInjection/SlowBlink/Services/HardwareService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using System;
using System.Threading;
using System.Device.Gpio;

using nanoFramework.Logging.Debug;

using Microsoft.Extensions.Logging;

namespace nanoFramework.SlowBlink
{
internal class HardwareService : IHardwareService, IDisposable
{
private Thread _thread;
private readonly ILogger _logger;
private readonly GpioController _gpioController;

public HardwareService()
{
_gpioController = new GpioController();

var loggerFactory = new DebugLoggerFactory();
_logger = loggerFactory.CreateLogger(nameof(HardwareService));
}

public HardwareService(ILoggerFactory loggerFactory)
{
_gpioController = new GpioController();
_logger = loggerFactory.CreateLogger(nameof(HardwareService));
}

public void StartBlinking(int ledPin)
{
GpioPin led = _gpioController.OpenPin(ledPin, PinMode.Output);
led.Write(PinValue.Low);

_thread = new Thread(() =>
{
while (true)
{
Thread.Sleep(2000);

led.Write(PinValue.High);
_logger.LogInformation("Led status: on");

Thread.Sleep(2000);

led.Write(PinValue.Low);
_logger.LogInformation("Led status: off");
}
});

_thread.Start();
}

public void Dispose()
{
_gpioController.Dispose();
}
}
}
14 changes: 14 additions & 0 deletions samples/DependencyInjection/SlowBlink/Services/IHardwareService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

namespace nanoFramework.SlowBlink
{
public interface IHardwareService
{
public void StartBlinking(int ledPin)
{
}
}
}
Loading

0 comments on commit 21c917f

Please sign in to comment.