読者です 読者をやめる 読者になる 読者になる

眠いしお腹すいたし(´・ω・`)

C#関連を主に書きます。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Xamarin.FormsでUnity.Configurationしてみた。

はじめに

引越しつらい現実逃避で記事書きました/(^o^)\

Unity

ゲーム作る方のじゃなくてDIとかする方のUnityのお話です。

www.nuget.org

現在、開発が止まって放置されているらしくて今後メンテの期待薄なので今更Unityのネタを書こうか迷ったんですがとりあえず書いてみることにしました。

UnityContainerの拡張メソッドにLoadConfigurationってあるのご存知ですか?

app.Configとかweb.configにContainerへのレジストを記述してLoadConfigurationすると、その設定どおりにContainerに登録を行ってくれます。

これ.NET45なプロジェクトだと使えるんだけどXamarinとかPCLでは使えないんです。

どうしてかというとSystem.Cofigurationに依存している拡張なのでSystem.Configurationが基本的に使えない環境を外してるんですね。

それを今回はPCLプロジェクトでもある程度使ってみるサンプルを作りました。

Xamarin.Formsへの対応

Windows8.1とかは対象外です。今回はAndroidで動作確認しています。たぶんiOSでも動くはずです。Macを既に梱包しちゃったので試せません。

UWPは頑張れば対応できそうなんですが今回は見送りました。

解説

プロジェクトの作成

まずはプロジェクトの作成を行います。

Xamarin.FormsプロジェクトをPCLにて作成してください。

PCLを.NET Standardに対応

tamafuyou.hatenablog.com

こちらの記事を参考にPCLプロジェクトを.NET Standardに対応させてください。

.NET Standardのバージョンは1.5としてください。

Unity.Configurationの追加

UnityのConfiguration機能をPCLで使用するためにUnity,Configurationというパッケージを使用します。

www.nuget.org

ソリューションのnugetマネージャーを開いてUnity.Configurationというパッケージを追加します。

Pre版ですので「プレリリースを含める」にチェックを入れて検索してください。

f:id:tamafuyou:20170207184230p:plain

PCL/Android/iOSに追加してください。

テスト動作用のインターフェースと実装クラスを追加します。

めんどくさいのでこんな感じで。

namespace App4
{
    public interface IHogeHoge
    {
        string GetHoge();
        string GetHogeHoge();
    }

    public class HogeHogeA : IHogeHoge
    {
        public string GetHoge() => "HogeA";
        public string  GetHogeHoge()=> "HogeHogeA";
    }
}

PCLにconfigファイルを追加します。

unity.configという名前でconfigファイルを追加します。

ビルドアクションは埋込リソースにしてください。

f:id:tamafuyou:20170207185333p:plain

ファイルの中はこんな感じで。

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <!-- Define Assemblies-->
  <assembly name="App4" />
  <!-- End Assemblies-->
  <!-- Define Namespaces-->
  <namespace name="App4" />
  <!-- End Namespaces-->
  <container>
    <register type="App4.IHogeHoge, App4" mapTo="App4.HogeHogeA, App4" />
  </container>
</unity>

他にも色々とできますがUnity.Configurationの使い方は別途ぐぐってください。

ConfigurationSectionReaderクラスを追加する

c# - How to Read a Configuration Section from XML in a Database? - Stack Overflow

こちらを参考にしました(コピペ)

こんな感じのクラスを追加しておきます。

    public class ConfigurationSectionReader<T> where T : ConfigurationSection, new()
    {
        public T GetSection(string sectionXml)
        {
            T section = new T();
            using (StringReader stringReader = new StringReader(sectionXml))
            using (XmlReader reader = XmlReader.Create(stringReader, new XmlReaderSettings() { CloseInput = true }))
            {
                reader.Read();
                section.GetType().GetMethod("DeserializeElement", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(section, new object[] { reader, true });
            }
            return section;
        }
    }

LoadConfigurationする

appクラスにてcontainerを作ってLoadConfigurationします。

        public App()
        {
            InitializeComponent();

            IUnityContainer container = null;

            var assembly = typeof(App).GetTypeInfo().Assembly;
            using (var stream = assembly.GetManifestResourceStream("App4.unity.config"))
            {
                using (TextReader reader = new StreamReader(stream))
                {
                    var configtext = reader.ReadToEnd();
                    var configreader = new ConfigurationSectionReader<UnityConfigurationSection>();
                    var sect = configreader.GetSection(configtext);
                    container = new UnityContainer();
                    container.LoadConfiguration(sect);
                }
            }

            MainPage = new App4.MainPage(container.Resolve<IHogeHoge>().GetHogeHoge());

            
        }

結果

f:id:tamafuyou:20170207191636p:plain

おわりに

Unity.Configurationライブラリに関しては余裕ができたらもう少し真面目に取り組んでみようかと思います。

ではでは( `ー´)ノ