Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何自动解析C#依赖关系?_C#_Unity3d - Fatal编程技术网

如何自动解析C#依赖关系?

如何自动解析C#依赖关系?,c#,unity3d,C#,Unity3d,我一直在阅读Unity的依赖注入,我理解它是一种东西,它允许您将类键入接口。我好奇的是,我必须这么做吗?在下面的场景中,在同一空间中有一个Terraingerator和TileCreator。如何将生成器中的TileCreator作为依赖项获取 引导我注册一个类型,但我在某处读到,只要该类在Unity Assets部分可见,它就可以自动注入它,我就是搞不懂语法(如果可能的话) 更新 我可以把所有的类放在一个文件中。。。有一个大的系统,可能会很烦人。与此同时,这是我将尝试的一种方法——总比完全不

我一直在阅读Unity的依赖注入,我理解它是一种东西,它允许您将类键入接口。我好奇的是,我必须这么做吗?在下面的场景中,在同一空间中有一个
Terraingerator
TileCreator
。如何将生成器中的
TileCreator
作为依赖项获取

引导我注册一个类型,但我在某处读到,只要该类在Unity Assets部分可见,它就可以自动注入它,我就是搞不懂语法(如果可能的话)

更新

我可以把所有的类放在一个文件中。。。有一个大的系统,可能会很烦人。与此同时,这是我将尝试的一种方法——总比完全不起作用要好

更新
看起来Unity应该能够查看类的构造函数并自动执行这些解析,然后将它们注入到类的构造函数中。这可能吗?

如果您正在为Unity3d引擎寻找DI,也许这会起作用(我没有使用它,但反馈是肯定的)

如果您正在谈论Microsoft的Unity DI库,您应该能够做到:

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(),
    WithMappings.FromMatchingInterface,
    WithName.Default);

我总是使用下面的代码。加载应用程序时,应用程序会在目录中查找所有DLL。这样,当您加载带有反射的类时,它会搜索DLL和EXE。您还可以添加更多路径进行搜索

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);

Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        string defaultFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

        string assemblyName = new AssemblyName(args.Name).Name;

        string assemblyNameDll = assemblyName + ".dll";
        string assemblyNameExe = assemblyName + ".exe";

        string assemblyPathDll = Path.Combine(defaultFolder, assemblyNameDll);
        string assemblyPathExe = Path.Combine(defaultFolder, assemblyNameExe);

        string assemblyPathToUse = null;
        if (File.Exists(assemblyPathDll))
        {
            assemblyPathToUse = assemblyPathExe;
        }
        else if (File.Exists(assemblyPathExe))
        {
            assemblyPathToUse = assemblyPathExe;
        }
        else
        {
            IEnumerable<string> merge = AssemblyFolders.Values;
            if (!string.IsNullOrEmpty(TempLoadingFolder))
            {
                merge = AssemblyFolders.Values.Union(new List<string>() { TempLoadingFolder });
            }
            foreach (var folder in merge)
            {
                assemblyPathDll = Path.Combine(folder, assemblyNameDll);
                assemblyPathExe = Path.Combine(folder, assemblyNameExe);

                if (File.Exists(assemblyPathDll))
                {
                    assemblyPathToUse = assemblyPathDll;
                    break;
                }
                else if (File.Exists(assemblyPathExe))
                {
                    assemblyPathToUse = assemblyPathExe;
                    break;
                }
            }
        }

        Assembly assembly = null;

        if (assemblyPathToUse != null && File.Exists(assemblyPathToUse))
        {
            assembly = Assembly.LoadFrom(assemblyPathToUse);
        }
        return assembly;
    }
AppDomain currentDomain=AppDomain.currentDomain;
currentDomain.AssemblyResolve+=新的ResolveEventHandler(currentDomain_AssemblyResolve);
程序集currentDomain_AssemblyResolve(对象发送方,ResolveEventArgs args args)
{
字符串defaultFolder=Path.GetDirectoryName(Assembly.getExecutionGassembly().Location);
字符串assemblyName=新的assemblyName(args.Name).Name;
字符串assemblyNameDll=assemblyName+“.dll”;
字符串assemblyNameExe=assemblyName+“.exe”;
字符串assemblyPathDll=Path.Combine(默认文件夹,assemblyNameDll);
字符串assemblyPathExe=Path.Combine(默认文件夹,assemblyNameExe);
字符串assemblyPathToUse=null;
if(File.Exists(assemblyPathDll))
{
assemblyPathToUse=assemblyPathExe;
}
else if(File.Exists(assemblyPathExe))
{
assemblyPathToUse=assemblyPathExe;
}
其他的
{
IEnumerable merge=AssemblyFolders.Values;
如果(!string.IsNullOrEmpty(TempLoadingFolder))
{
merge=AssemblyFolders.Values.Union(新列表(){TempLoadingFolder});
}
foreach(合并中的var文件夹)
{
assemblyPathDll=Path.Combine(文件夹,assemblyNameDll);
assemblyPathExe=Path.Combine(文件夹,assemblyNameExe);
if(File.Exists(assemblyPathDll))
{
assemblyPathToUse=assemblyPathDll;
打破
}
else if(File.Exists(assemblyPathExe))
{
assemblyPathToUse=assemblyPathExe;
打破
}
}
}
Assembly=null;
如果(assemblyPathToUse!=null&&File.Exists(assemblyPathToUse))
{
assembly=assembly.LoadFrom(assemblyPathToUse);
}
返回组件;
}

不,您不必使用接口,也可以注册和解析具体类型

例如,您可以注册TerrainGenerator和TileCreator,如下所示:

var myTileCreator = new TileCreator();
container.RegisterType<TerrainGenerator>(new PerThreadLifetimeManager(), new InjectionFactory(c => new TerrainGenerator(myTileCreator)));
var myTileCreator=new TileCreator();
RegisterType(新PerThreadLifetimeManager(),新InjectionFactory(c=>newterraingenerator(myTileCreator));
要解决Terraingerator问题,请执行以下操作:

Terraingerator generator=container.Resolve();
要使用不同的TileCreator解析Terraingerator,请执行以下操作:

terraingerator generator=container.Resolve(新参数覆盖(“tileCreator”,新tileCreator());
您可能需要阅读更多有用的信息,如属性注入等


希望这能有所帮助。

不要认为这些类是否在同一个文件中很重要。Unity需要知道如何创建给定类型的实例

如果使用RegisterInstance,则每次调用类型的Resolve时都会返回作为参数传递的特定对象。如果该类型是使用RegisterType注册的(或者根本没有为具体类注册),Unity将尝试使用具有最多参数的构造函数来实例化该类型。对于每种参数类型,Unity将尝试递归地解析它们

注册接口类型到具体类型的映射是必需的,但注册具体类型本身是可选的

示例代码:

using Microsoft.Practices.Unity;
using System;

namespace Unity
{  
    interface IFooBar
    {
        string Message();
    }

    class Foo
    {
        string msg;

        public Foo()
        {
            msg = "Hello";
        }

        public override string ToString()
        {
            return msg;
        }
    }

    class Bar
    {
        private Foo _f;
        private IFooBar _fb;
        public Bar(Foo f, IFooBar fb)
        {
            this._f = f;
            this._fb = fb;
        }

        public override string ToString()
        {
            return _f.ToString() + " World " + _fb.Message();
        }
    }

    class FooBar : IFooBar
    {
        public string Message()
        {
            return "Unity!";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            UnityContainer container = new UnityContainer();
            container.RegisterType<IFooBar, FooBar>(); // required
            container.RegisterType<Foo>(); // optional
            container.RegisterType<Bar>(); // optional

            var mybar = container.Resolve<Bar>();

            Console.WriteLine(mybar);
        }
    }
}
使用Microsoft.Practices.Unity;
使用制度;
名称空间统一性
{  
接口IFooBar
{
字符串消息();
}
福班
{
串味精;
公共食物(
{
msg=“你好”;
}
公共重写字符串ToString()
{
返回味精;
}
}
分类栏
{
私人食品;;
私人IFooBar_fb;
公共酒吧(Foo f、IFooBar fb)
{
这个;
这个。_fb=fb;
}
公共重写字符串ToString()
{
返回_f.ToString()+“World”+_fb.Message();
}
}
类FooBar:IFooBar
{
公共字符串消息()
{
返回“团结!”;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
UnityContainer容器=新的UnityContainer();
container.RegisterType();//必需
container.RegisterType();//可选
容器注册
TerrainGenerator generator = container.Resolve<TerrainGenerator>(new ParameterOverride("tileCreator", new TileCreator()));
using Microsoft.Practices.Unity;
using System;

namespace Unity
{  
    interface IFooBar
    {
        string Message();
    }

    class Foo
    {
        string msg;

        public Foo()
        {
            msg = "Hello";
        }

        public override string ToString()
        {
            return msg;
        }
    }

    class Bar
    {
        private Foo _f;
        private IFooBar _fb;
        public Bar(Foo f, IFooBar fb)
        {
            this._f = f;
            this._fb = fb;
        }

        public override string ToString()
        {
            return _f.ToString() + " World " + _fb.Message();
        }
    }

    class FooBar : IFooBar
    {
        public string Message()
        {
            return "Unity!";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            UnityContainer container = new UnityContainer();
            container.RegisterType<IFooBar, FooBar>(); // required
            container.RegisterType<Foo>(); // optional
            container.RegisterType<Bar>(); // optional

            var mybar = container.Resolve<Bar>();

            Console.WriteLine(mybar);
        }
    }
}